IO复用select实现TCP服务端
c
#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客户端
c
#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;
}