#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define MAXLINE 80
#define port 8888
#define FD_SETSIZE 1024
int main(int argc,char* argv[]){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(sockfd,(struct sockaddr*)&server,sizeof(server));
ret = listen(sockfd,10);
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client[FD_SETSIZE];
int maxfd = sockfd;
int i ;
int maxi = -1;
int nready;
for(i = 0;i<FD_SETSIZE;i++){
client[i] = -1;//用-1初始化client[]
}
fd_set allset,rset;
int connfd;
char str[MAXLINE];
int sock;
FD_ZERO(&allset);
FD_SET(sockfd,&allset);//构造select监控文件描述符集
int n;
char buf[MAXLINE];
for(;;){
rset = allset;
nready = select(maxfd+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(sockfd,&rset)){
//new client connection
connfd = accept(sockfd,(struct sockaddr*)&client_addr,&client_len);
printf("recieved form %s \t %d\n",inet_ntop(AF_INET,&client_addr.sin_addr,str,sizeof(str)),ntohs(client_addr.sin_port));
for(i = 0;i<FD_SETSIZE;i++){
if(client[i]<0){
client[i] = connfd;//保存accet返回的文件描述符到cleint[]里面
break;
}
}
//printf("1111\n");
if(i == FD_SETSIZE){
fputs("too many clients\n",stderr);
exit(1);
}
//printf("22\n");
FD_SET(connfd,&allset);//添加一个新的文件描述符到监控信号集
//FD_SET(connfd,&rset);
if(connfd>maxfd){
maxfd = connfd;//select第一个参数的需要
}
if(i>maxi){
maxi = i;//更新client的最大下标值
}
//printf("3333");
if(--nready == 0){
continue;//如果没有更多的就绪文件描述符继续回到上面的select阻塞监听,负责处理未处理玩的就绪文件描述符
}
//printf("444");
}
for(i = 0;i<maxi;i++){
//检测哪个client有数据就绪
if((sock = client[i])<0){
continue;
}
if(FD_ISSET(sock,&rset)){
if((n = read(sock,buf,MAXLINE)) == 0){
//当client关闭链接的时候,服务器段也关闭对应的链接
close(sock);
FD_CLR(sock,&allset);//解除select监控次文件描述符
client[i] = -1;
}
else{
int j ;
for(j = 0;j<n;j++){
buf[j] = toupper(buf[j]);
}
write(STDOUT_FILENO,buf,n);
}
if(--nready == 0){
break;
}
}
}
}
close(sockfd);
return 0;
}
服务端
#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<stdlib.h>
#define port 8888
#define buflen 1024
int main(int argc,char* argv[]){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
int len ;
if(sockfd<0){
printf("socket failed\n");
exit(1);
}
char recvbuf[buflen];
struct sockaddr_in serv_addr;
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr);
int ret = connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
printf("start to connect...\n");
while(fgets(recvbuf,sizeof(recvbuf),stdin)!=NULL){
write(sockfd,recvbuf,strlen(recvbuf));
len = read(sockfd,recvbuf,sizeof(recvbuf));
write(STDOUT_FILENO,recvbuf,len);
}
return 0;
}
客户端