#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BUFSIZE 512
#define RET_ERR -1
#define RET_OK 0
#define Debug_UserLog printf
#define Debug_SysLog printf
#define MAX_SOCKET 10000
#define serial_num 10
void SetNonBlock(int fd)
{
int flag = fcntl ( fd, F_GETFL, 0 );
fcntl ( fd, F_SETFL, flag | O_NONBLOCK );
}
int main(int argc, char** argv)
{
int iRet = RET_OK;
if(4 != argc)
{
Debug_UserLog("Parameter: ServerIP Message ServerPort", RET_ERR);
return RET_ERR;
}
in_port_t i16_port = atoi(argv[3]);
if(0 >= i16_port)
{
Debug_UserLog("port number is wrong", RET_ERR);
return RET_ERR;
}
int sk[MAX_SOCKET];
for(int i=0;i<serial_num;i++){
sk[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}
if(-1 == sk)
{
Debug_SysLog("open socket failed!");
return RET_ERR;
}
struct sockaddr_in sa = {0};
sa.sin_family = AF_INET;
sa.sin_port = htons(i16_port);
struct sockaddr_in *psa = &sa;
iRet = inet_pton(AF_INET, argv[1], &psa->sin_addr.s_addr);
if(0 == iRet)
{
Debug_UserLog("inet_pton failed, invalid address!", RET_ERR);
close(sk); //有问题没处理
return RET_ERR;
}
else if(iRet < 0)
{
Debug_SysLog("inet_pton failed");
close(sk); //有问题没处理
return RET_ERR;
}
for(int i=0;i<serial_num;i++){
if(connect(sk[i], (struct sockaddr*)&sa, sizeof(sa)) < 0)
{
Debug_SysLog("connect failed");
close(sk[i]); //有问题没处理
return RET_ERR;
}
}
for(int i=0;i<serial_num;i++){
SetNonBlock(sk[i]);
}
int efd;
efd = epoll_create(10);
if(efd == -1)
{
perror("epoll_create error!");
exit(1);
}
struct epoll_event event;
struct epoll_event events[serial_num];
event.events = EPOLLOUT | EPOLLET;
for(int i=0;i<serial_num;i++){
event.data.fd = sk[i];
epoll_ctl(efd, EPOLL_CTL_ADD, sk[i], &event); //加到管理的组
}
// getchar();
int loop = 0;
while(1)
{
ssize_t numBytesRcvd = 0;
char buffer[BUFSIZE] = {0};
int n = 0;
int i = 0;
if(loop == 1)
{
break;
}
n = epoll_wait(efd, events, serial_num, -1);
printf("%d\n", n);
for(i = 0; i < n; i++)
{
if(events[i].events & EPOLLOUT)
{
printf("EPOLLOUT...............\n");
//snprintf(buffer, BUFSIZE, "i am process %d, just say: %s\n", getpid(), argv[2]);
snprintf(buffer, BUFSIZE,"GET / HTTP/1.1\r\nHOST: www.baidu.com\r\n\r\n" );
int n = strlen(buffer);
int nsend = 0;
while(n > 0)
{
//nsend = send(events[i].data.fd, buffer + nsend, n, 0);
nsend = write(events[i].data.fd, buffer + nsend, n);
if(nsend < 0 && errno != EAGAIN)
{
perror("write");
Debug_SysLog("send failed");
close(events[i].data.fd);
return RET_ERR;
}
n -= nsend;
}
event.events = EPOLLIN | EPOLLET;
event.data.fd = events[i].data.fd;
epoll_ctl(efd, EPOLL_CTL_MOD, events[i].data.fd, &event); //加到管理的组
}
if(events[i].events & EPOLLIN)
{
printf("EPOLLIN...............\n");
memset(buffer, 0, BUFSIZE);
int len = strlen(buffer);
int n = 0;
int nrecv = 0;
while(1){
nrecv = read(events[i].data.fd, buffer + n, BUFSIZE - 1) ;
if(nrecv == -1 && errno != EAGAIN)
{
perror("read error!");
}
if((nrecv == -1 && errno == EAGAIN) || nrecv == 0)
{
break;
}
n += nrecv;
}
//loop = 1;
printf("%s\n", buffer);
}
}
}
for(int i=0;i<serial_num;i++){
close(sk[i]);
}
close(efd);
return RET_OK;
}
客户端 IO复用 多路复用 epoll
猜你喜欢
转载自blog.csdn.net/qq_23100787/article/details/80231742
今日推荐
周排行