4,436
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#define PORT 8888
#define MAX_CONNECT 10
#define IN_ET_MODE EPOLLIN | EPOLLET
#define OUT_ET_MODE EPOLLOUT | EPOLLET
#define sys_err(ret, str) \
do \
{ \
if (ret == -1) \
{ \
perror(str); \
exit(-1); \
} \
} while (0)
int main(int argc, char const *argv[])
{
int sfd, cfd, epfd, ret, rdlen, i, EventNum;
char buf[BUFSIZ] = {0};
char str[INET_ADDRSTRLEN] = {0};
socklen_t socklen = sizeof(struct sockaddr_in);
struct sockaddr_in srv, clt;
struct epoll_event evt, evts[MAX_CONNECT];
memset(&srv, 0, sizeof(srv));
memset(&clt, 0, sizeof(clt));
memset(&evt, 0, sizeof(evt));
memset(&evts, 0, sizeof(evts));
sfd = socket(AF_INET, SOCK_STREAM, 0);
sys_err(sfd, "socket");
// 1. 创建epoll_event句柄,句柄中含有红黑数根节点
epfd = epoll_create(10);
sys_err(epfd, "epoll_create");
// 2. 把sfd添加至红黑树中
evt.events = EPOLLIN;
evt.data.fd = sfd;
ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &evt);
sys_err(ret, "epoll_ctl");
//端口复用
int opt = 1;
ret = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sys_err(ret, "setsockopt");
srv.sin_family = AF_INET;
srv.sin_port = htons(PORT);
srv.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sfd, (struct sockaddr *)&srv, socklen);
sys_err(ret, "bind");
ret = listen(sfd, 128);
sys_err(ret, "listen");
while (1)
{
printf("epoll_wait()开始监听事件\n");
EventNum = epoll_wait(epfd, evts, MAX_CONNECT, -1);
sys_err(EventNum, "epoll_wait");
for (i = 0; i < EventNum; i++)
{
if (evts[i].data.fd == sfd) //连接请求
{
printf("有连接请求事件 %d\n", EventNum);
cfd = accept(sfd, (struct sockaddr *)&clt, &socklen);
sys_err(cfd, "accept");
printf("客户端 %d [%s:%u] 已连接\n",
cfd,
inet_ntop(AF_INET, &clt.sin_addr.s_addr, str, sizeof(str)),
ntohs(clt.sin_port));
//非阻塞
int flag = fcntl(cfd, F_GETFL);
flag |= O_NONBLOCK;
fcntl(cfd, F_SETFL, flag);
//添加到epoll_event句柄
evt.events = EPOLLIN | EPOLLET;
evt.data.fd = cfd;
ret = epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &evt);
sys_err(ret, "epoll_ctl");
}
else //数据请求
{
printf("有数据请求事件 %d\n", EventNum);
int sockfd = evts[i].data.fd;
//printf("客户端 %d 数据请求:\n",sockfd);
while (1)
{
memset(buf, 0, sizeof(buf));
rdlen = read(sockfd, buf, 3);
//printf("read return %d\n",rdlen);
if (rdlen < 0)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
{
printf("[EAGAIN] errno = %d, return %d\n", errno, rdlen);
break;
}
else
{
perror("read");
exit(-1);
}
}
else if (rdlen > 0)
{
printf("[RECV] %s, %d\n", buf, rdlen);
int j;
for (j = 0; j < rdlen; ++j)
buf[j] = toupper(buf[j]);
write(sockfd, buf, rdlen);
}
else
{
ret = epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL);
sys_err(ret, "epoll_ctl");
close(sockfd);
printf("客户端 %d 断开连接\n", sockfd);
break;
}
}
}
}
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <signal.h>
#define PORT 8888
#define sys_err(ret, str) \
do \
{ \
if (ret == -1) \
{ \
perror(str); \
exit(-1); \
} \
} while (0)
int cfd;
void sigproc(int signo)
{
printf("收到ctrl + C 信号,断开连接\n");
close(cfd);
//shutdown(cfd, SHUT_RDWR);
exit(-1);
}
int main(int argc, char const *argv[])
{
char buf[BUFSIZ] = {"aaaaaaaaaa"};
struct sockaddr_in srv;
memset(&srv, 0, sizeof(srv));
signal(SIGINT, sigproc);
cfd = socket(AF_INET, SOCK_STREAM, 0);
srv.sin_family = AF_INET;
srv.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &srv.sin_addr.s_addr);
socklen_t len = sizeof(struct sockaddr_in);
int ret = connect(cfd, (struct sockaddr *)&srv, len);
sys_err(ret, "connect");
int n = 3;
while (n--)
{
ret = write(cfd, buf, strlen(buf));
printf("[SEND] %s, %d\n", buf, ret);
sleep(5);
}
//shutdown(cfd, SHUT_RDWR);
close(cfd);
return 0;
}