select实现tcp并发服务器
#include "test.h"
#define SER_IP "192.168.42.106"
#define SER_PORT 8888
int create_socket()
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("socket error");
exit(-1);
}
printf("sfd = %d\n", sfd);
return sfd;
}
int start_reuse(int sfd)
{
int reuse = -1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("setsockopt error");
exit(-1);
}
printf("端口号快速重用成功\n");
return reuse;
}
void start_listen(int sfd)
{
if (listen(sfd, 128) == -1)
{
perror("listen error");
exit(-1);
}
printf("listen success\n");
}
int main(int argc, const char *argv[])
{
int sfd = create_socket();
int reuse = start_reuse(sfd);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP);
if (bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
{
perror("bind error");
return -1;
}
start_listen(sfd);
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin);
int newfd = -1;
char sbuf[128] = "";
fd_set readfds, tempfds;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sfd, &readfds);
int maxfd = sfd;
struct sockaddr_in cin_arr[1024];
while(1)
{
tempfds = readfds;
int res = select(maxfd + 1, &tempfds, NULL, NULL, NULL);
if (res == -1)
{
perror("select error");
exit(-1);
}
else if (res == 0)
{
printf("time out\n");
exit(-1);
}
for (int i = 0; i < maxfd; i++)
{
if (!FD_ISSET(i, &tempfds))
{
continue;
}
if (i == sfd)
{
newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
if (newfd == -1)
{
perror("accept error");
exit(-1);
}
printf("newfd=%d 您已有新客户上线\n", newfd);
printf("客户端IP: %s, 端口号: %d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
FD_SET(newfd, &readfds);
cin_arr[newfd] = cin;
if (newfd > maxfd)
{
maxfd = newfd;
}
}
else if (i == 0)
{
fgets(sbuf, sizeof(sbuf), stdin);
sbuf[strlen(sbuf) - 1] = 0;
printf("触发了键盘输入事件: %s\n", sbuf);
for (int k = 4; k < maxfd; k++)
{
send(k, sbuf, strlen(sbuf), 0);
}
}
else
{
char rbuf[128] = "";
bzero(rbuf, sizeof(rbuf));
int res = recv(i, rbuf, sizeof(rbuf), 0);
if (res == 0)
{
printf("客户端已下线\n");
close(i);
FD_CLR(i, &readfds);
for (int j = maxfd; j >= 0; j--)
{
if (FD_ISSET(j, &readfds))
{
maxfd = j;
break;
}
}
continue;
}
printf("[%s:%d]: %s\n", inet_ntoa(cin_arr[i].sin_addr), ntohs(cin_arr[i].sin_port), rbuf);
strcat(rbuf, "*_*");
send(i, rbuf, strlen(rbuf), 0);
}
}
}
close(sfd);
return 0;
}
poll实现tcp客户端
#include "test.h"
#define SER_IP "192.168.191.128"
#define SER_PORT 8888
#define CLI_IP "192.168.191.128"
#define CLI_PORT 9999
int create_socket()
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("socket error");
exit(-1);
}
printf("sfd = %d\n", sfd);
return sfd;
}
int start_reuse(int sfd)
{
int reuse = -1;
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("setsockopt error");
exit(-1);
}
printf("端口号快速重用成功\n");
return reuse;
}
void start_listen(int sfd)
{
if (listen(sfd, 128) == -1)
{
perror("listen error");
exit(-1);
}
printf("listen success\n");
}
int main(int argc, const char *argv[])
{
int sfd = create_socket();
int reuse = start_reuse(sfd);
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(CLI_PORT);
cin.sin_addr.s_addr = inet_addr(CLI_IP);
if (bind(sfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
{
perror("bind error");
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP);
if (connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
{
perror("connect error");
exit(-1);
}
printf("connect success\n");
struct pollfd pfd[2];
pfd[0].fd = 0;
pfd[0].events = POLLIN;
pfd[1].fd = sfd;
pfd[1].events = POLLIN;
char wbuf[128] = "";
while(1)
{
int res = poll(pfd, 2, -1);
if (res == -1)
{
perror("poll error");
exit(-1);
}
else if (res == 0)
{
printf("time out\n");
exit(-1);
}
if (pfd[0].revents == POLLIN)
{
bzero(wbuf, sizeof(wbuf));
printf("请输入>>>");
fgets(wbuf, sizeof(wbuf), stdin);
wbuf[strlen(wbuf) - 1] = 0;
send(sfd, wbuf, strlen(wbuf), 0);
printf("发送成功\n");
if (strcmp(wbuf, "quit") == 0)
{
break;
}
}
if (pfd[1].revents == POLLIN)
{
bzero(wbuf, sizeof(wbuf));
recv(sfd, wbuf, sizeof(wbuf), 0);
printf("收到消息: %s\n", wbuf);
}
}
close(sfd);
return 0;
}