select的TCP服务器
#include <code.h>
#define PORT 1100
#define IP "192.168.124.32"
int deal_keyboardEvent(fd_set readfds, struct sockaddr_in pSaveCin[]);
int deal_CliConnectEvent(int sfd, struct sockaddr_in* saveCin, fd_set* preadfds, int* pmaxfd);
int deal_CliTalkEvent(int i, struct sockaddr_in saveCin[], fd_set *preadfds, int *pmaxfd);
int main(int argc, const char *argv[])
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("socket");
return -1;
}
printf("创建流式套接字成功 sfd=%d __%d__\n", sfd, __LINE__);
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
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)) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("bind");
return -1;
}
printf("bind success __%d__\n", __LINE__);
if(listen(sfd, 128) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("listen");
return -1;
}
printf("listen success __%d__\n", __LINE__);
fd_set readfds, tempfds;
FD_ZERO(&readfds);
FD_SET(0, &readfds);
FD_SET(sfd, &readfds);
int maxfd = sfd;
int s_res;
char buf[128];
ssize_t res ;
int newfd = -1;
struct sockaddr_in saveCin[1024-3];
while(1)
{
tempfds = readfds;
s_res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
if(s_res < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("select");
return -1;
}
else if(0 == s_res)
{
printf("time out....\n");
break;
}
printf("__%d__\n", __LINE__);
for(int i=0; i<=maxfd; i++)
{
if(FD_ISSET(i, &tempfds) == 0)
continue;
if(0 == i){
printf("触发键盘输入事件\n");
deal_keyboardEvent(readfds, saveCin);
}
else if(i == sfd){
printf("触发客户端连接事件\n");
deal_CliConnectEvent(sfd, saveCin, &readfds, &maxfd);
}
else
{
printf("触发客户端交互事件\n");
deal_CliTalkEvent(i, saveCin, &readfds, &maxfd);
}
}
}
close(sfd);
return 0;
}
int deal_CliTalkEvent(int i, struct sockaddr_in saveCin[], fd_set *preadfds, int *pmaxfd)
{
char buf[128] = "";
bzero(buf, sizeof(buf));
ssize_t res = recv(i, buf, sizeof(buf), 0);
if(res < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("recv");
return -1;
}
else if(0 == res)
{
printf("[%s:%d] 客户端下线 newfd=%d __%d__\n", inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i, __LINE__);
close(i);
FD_CLR(i, preadfds);
while(FD_ISSET(*pmaxfd, preadfds)==0 && (*pmaxfd--)>0);
return -1;
}
printf("[%s:%d] newfd=%d %s __%d__\n",inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i, buf, __LINE__);
strcat(buf, "*_*");
if(send(i, buf, sizeof(buf), 0) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("send");
return -1;
}
printf("send success __%d__\n", __LINE__);
return 0;
}
int deal_CliConnectEvent(int sfd, struct sockaddr_in* saveCin, fd_set* preadfds, int* pmaxfd)
{
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
if(newfd < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("accept");
return -1;
}
printf("[%s:%d] 客户端连接成功 newfd=%d __%d__\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);
saveCin[newfd-3] = cin;
FD_SET(newfd, preadfds);
*pmaxfd = newfd>*pmaxfd ? newfd:*pmaxfd;
return 0;
}
int deal_keyboardEvent(fd_set readfds, struct sockaddr_in pSaveCin[])
{
int sndfd;
char buf[128];
int res=scanf("%d %s", &sndfd, buf);
while(getchar() != '\n');
if(res != 2)
{
printf("请输入正确格式: fd string\n");
return -1;
}
if(sndfd<0 || sndfd>1023 || FD_ISSET(sndfd, &readfds) == 0)
{
printf("请输入正确的文件描述符\n");
return -1;
}
if(send(sndfd, buf, sizeof(buf), 0) < 0)
{
perror("send");
return -1;
}
printf("发送给[%s:%d] fd=%d客户端 成功 __%d__\n",inet_ntoa(pSaveCin[sndfd-3].sin_addr), ntohs(pSaveCin[sndfd-3].sin_port), sndfd, __LINE__);
return 0;
}
poll的客户端
#include <code.h>
int main(int argc, const char *argv[])
{
if(argc < 3)
{
printf("请在命令行传入服务器的port 和 ip\n");
return -1;
}
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("socket");
return -1;
}
printf("create socket success, cfd=%d __%d__\n", cfd, __LINE__);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(argv[1]));
sin.sin_addr.s_addr = inet_addr(argv[2]);
if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("connect");
return -1;
}
printf("connect server[%s:%s] success __%d__\n", argv[2], argv[1], __LINE__);
struct pollfd fds[2];
fds[0].fd = 0;
fds[0].events = POLLIN;
fds[1].fd = cfd;
fds[1].events = POLLIN;
char buf[128] = "";
ssize_t res;
int p_res;
while(1)
{
p_res = poll(fds, 2, -1);
if(p_res < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("poll");
return -1;
}
else if(0 == p_res)
{
printf("time out....\n");
break;
}
if((fds[0].revents & POLLIN) != 0)
{
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
if(send(cfd, buf, sizeof(buf), 0) < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("send");
return -1;
}
printf("send success __%d__\n", __LINE__);
}
if(fds[1].revents & POLLIN)
{
bzero(buf, sizeof(buf));
res = recv(cfd, buf, sizeof(buf), 0);
if(res < 0)
{
fprintf(stderr, "line:%d ", __LINE__);
perror("recv");
return -1;
}
else if(0 == res)
{
printf("服务器下线 __%d__\n", __LINE__);
break;
}
printf(":%s __%d__\n", buf, __LINE__);
}
}
close(cfd);
return 0;
}