IO模型之epoll实现服务器客户端收发

 epoll.ser


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERR_MSG(msg)                  \
	{                                 \
		printf("__%d__\n", __LINE__); \
		perror(msg);                  \
	}
#define IP "192.168.250.100"
#define PORT 12345

int main(int argc, const char *argv[])
{
	struct epoll_event event;
	struct epoll_event events[10]; // 存放就绪事件描述符的数组

	// 创建流式套接字
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("socket success\n");

	// 允许端口快速被复用
	int reuse = 1;
	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	// 绑定服务器的IP和端口
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind success\n");

	// 将套接字设置为被动监听状态
	if (listen(sfd, 128) < 0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success\n");

	// 获取链接成功后的套接字,拿到文件描述符
	struct sockaddr_in cin;
	struct sockaddr_in savecin[1024];
	socklen_t len = sizeof(cin);
	char s[128] = "";
	char s1[128] = "";
	ssize_t res = 0;
	int num;
	int newfd, epfd;

	epfd = epoll_create(1);
	if (epfd < 0)
	{
		printf("epoll_create filed\n");
		exit(-1);
	}

	// 将套接字添加到红黑树
	event.events = EPOLLIN;
	event.data.fd = sfd;
	if (epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &event) < 0)
	{
		printf("epoll_ctl add filed\n");
	}

	while (1)
	{
		int i;
		int ret = epoll_wait(epfd, events, 10, -1);
		if (ret < 0)
		{
			printf("epoll_wait filed\n");
			exit(-1);
		}

		for (i = 0; i < ret; i++)
		{
			if (events[i].data.fd == sfd) // 套接的文件描述符 来客户端了
			{
				newfd = accept(sfd, (struct sockaddr *)&cin, &len);
				if (newfd < 0)
				{
					ERR_MSG("accept");
					return -1;
				}
				bzero(s1, sizeof(s1));
				printf("客户端连接成功\n");

				savecin[newfd] = cin;
				// 添加准备就绪事件进入epoll;
				event.events = EPOLLIN; // 读事件
				event.data.fd = newfd;
				if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &event) < 0)
				{
					printf("epoll_ctl add filed\n");
				}
			}
			else
			{
				if (events[i].events & EPOLLIN)
				{
					int fd1 = events[i].data.fd;
					bzero(s, sizeof(s));
					res = recvfrom(events[i].data.fd, s, sizeof(s), 0, NULL, NULL);
					if (0 == res)
					{
						printf("客户端关闭\n");
						close(i);
						if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd1, &event) < 0)
						{
							printf("epoll_ctl sub filed\n");
						}
					}
					else if (res < 0)
					{
						ERR_MSG("recv");
						return -1;
					}
					printf("接收到的内容是:%s\n", s);
					printf("请输入要发送的内容:");

					scanf("%s", s1);
					if (write(events[i].data.fd, s1, sizeof(s1)) < 0)
					{
						ERR_MSG("write");
					}
					printf("发送成功\n");
				}
			}
		}
	}

	if (close(sfd) < 0)
	{
		ERR_MSG("close");
		return -1;
	}
	return 0;
}

epoll.cri

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ERR(msg)                      \
	{                                 \
		printf("__%d__\n", __LINE__); \
		perror(msg);                  \
		return -1;                    \
	}
#define PORT 12345
#define IP "192.168.250.100"

int main(int argc, const char *argv[])
{
	
	//  创建套接字
	int fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0)
	{
		ERR("socket");
	}
	printf("socket success\n");

	// 连接服务器
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	socklen_t len = sizeof(sin);

	if (connect(fd, (struct sockaddr *)&sin, len) < 0)
	{
		ERR("connect");
	}
	printf("connect success\n");

	// 读取数据
	char s[128] = "";
	char s1[128] = "";
	ssize_t res = 0;
	int num;

	while (1)
	{
		printf("请输入要发送的内容:");
		
		scanf("%s", s1);
		if (write(fd, s1, sizeof(s1)) < 0)
		{
			ERR("write");
		}
		printf("发送成功\n");
		res = recvfrom(fd, s, sizeof(s), 0, NULL, NULL);
		printf("接收的内容:%s\n",s);
	}

	if (close(fd) < 0)
	{
		ERR("close");
	}

	return 0;
}

result

 IO模型之epoll实现服务器客户端收发_第1张图片

 

 

你可能感兴趣的:(服务器,算法,运维)