IO复用select实现TCP服务端
#define IP "192.168.125.196"
#define PORT 8888
int main(int argc, const char *argv[])
{int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd == -1){perror("socket");return -1;}int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt");return -1;}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)) == -1){perror("bind");return -1;}if(listen(sfd, 128) == -1){perror("listen");return -1;}fd_set readfds, tempfds;FD_ZERO(&readfds);FD_SET(sfd, &readfds);int maxfd = sfd;int newfd = -1;struct sockaddr_in cin_arr[1024] = {0};struct sockaddr_in cin;socklen_t cinlen = sizeof(cin);char rbuf[128] = {0};while(1){tempfds = readfds;int res = select(maxfd+1, &tempfds, NULL, NULL, NULL);if(res == -1){perror("select");return -1;}else if(res == 0){printf("timeout\n");return -1;}for(int i=0; i<=maxfd; i++){if(!FD_ISSET(i, &tempfds)){continue;}if(i == sfd){newfd = accept(sfd, (struct sockaddr *)&cin, &cinlen);if(newfd == -1){perror("accept");return -1;}printf("[%s:%d]:online\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));cin_arr[newfd] = cin;FD_SET(newfd, &readfds);if(newfd > maxfd){maxfd = newfd;}}else{bzero(rbuf, sizeof(rbuf));int res = recv(i, rbuf, sizeof(rbuf), 0);if(res == 0){ printf("offline\n");close(i);FD_CLR(i, &readfds);for(int k=maxfd; k>=sfd; k--){if(FD_ISSET(k, &readfds)){maxfd = k;break;}}continue;}printf("[%s:%d]:%s\n", inet_ntoa(cin_arr[i].sin_addr), ntohs(cin_arr[i].sin_port), rbuf);for(int j=4; j<=maxfd; j++){if(j != i){send(j, rbuf, strlen(rbuf), 0);}}}}}close(sfd);return 0;
}
IO复用poll实现TCP客户端
#include <myhead.h>
#define S_IP "192.168.125.196"
#define S_PORT 8888
#define C_IP "192.168.125.196"
#define C_PORT 7777
int main(int argc, const char *argv[])
{int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1){perror("socket");return -1;}int reuse = 1;if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){perror("setsockopt");return -1;}struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(C_PORT);cin.sin_addr.s_addr = inet_addr(C_IP);if(bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1){perror("bind");return -1;}struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(S_PORT);sin.sin_addr.s_addr = inet_addr(S_IP);if(connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){perror("connect");return -1;}printf("connect success\n");struct pollfd pfd[2];pfd[0].fd = 0;pfd[0].events = POLLIN;pfd[1].fd = cfd;pfd[1].events = POLLIN;char rbuf[128] = {0};char wbuf[128] = {0};while(1){int ret = poll(pfd, 2, -1);if(ret == -1){perror("poll");return -1;}else if(ret == 0){printf("timeout\n");return -1;}if(pfd[0].revents == POLLIN){bzero(wbuf, sizeof(wbuf));fgets(wbuf, sizeof(wbuf), stdin);int len = strlen(wbuf);if(wbuf[len-1] == '\n'){wbuf[len-1] = 0;}send(cfd, wbuf, len, 0);}if(pfd[1].revents == POLLIN){bzero(rbuf, sizeof(rbuf));int res = recv(cfd, rbuf, sizeof(rbuf), 0);if(res == 0){printf("offline\n");break;}printf("[%s:%d]:%s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), rbuf);}}return 0;
}