selectserver.c
socket:建立套接字 bind:绑定 listen:监听 select: accept:接收消息
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <string.h>
#define PORT 8000
int main()
{
int sockfd, ret;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd)
{
perror("socket"); //如果创建失败
exit(1);
}
memset(&server_addr ,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=PORT; //端口号必须是网络字节序 有时需要大小端转换
server_addr.sin_addr.s_addr=inet_addr("192.168.1.10");
int length=sizeof(server_addr);
ret=bind(sockfd, (struct sockaddr *)&server_addr, length);
if(-1==ret)
{
perror("bind"); //如果绑定失败
exit(2);
}
/**********定义服务器的最大可连接数目*******/
ret=listen(sockfd,5);
if(-1==ret) //5为等待的数目
{
perror("listen"); //监听套接字
exit(3);
}
int MaxFd, i=0;
int fd[1000]={0};
char buf[32]={0};
fd_set ReadFd, tmpfd;
FD_ZERO(&ReadFd); //初始化集合
FD_SET(sockfd, &ReadFd); //sockfd先加到集合里面去
MaxFd=sockfd;
while(1)
{
tmpfd=ReadFd;
ret=select(MaxFd+1, &tmpfd, NULL, NULL, NULL); //NULL 为阻塞的
if(-1==ret)
{
perror("select");
}
if(FD_ISSET(sockfd, &tmpfd)) //如果是sockfd有消息
{
length=sizeof(client_addr);
memset(&client_addr, 0, sizeof(client_addr));
fd[i]=accept(sockfd,(struct sockaddr *)&client_addr, &length);
if(-1==fd[i])
{
perror("accept");
}
FD_SET(fd[i], &ReadFd); //新的fd添加到集合
if(fd[i]>MaxFd)
{
MaxFd = fd[i]; //更新MaxFd
}
i++;
}
else //有客户端发消息
{
int j=0;
for(j=0;j<i;j++)
{
if(FD_ISSET(fd[j], &tmpfd))
{
ret = recv(fd[j], buf, sizeof(buf), 0);
if(-1==ret)
{
perror("recv");
}
printf("recv %s from %d \n", buf, fd[j]);
memset(buf ,0, sizeof(buf));
break; //消息已经读出 退出循环
}
}
}
}
return 0;
}
客户端的代码和之前的一样