//server.c
//version1server和clien
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
void Usage(char* proc)
{
printf("Uasge:%s[local_ip][local_port]\n",proc);
exit(2);
}
int startup(char* ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket\n");
exit(3);
}
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(port);
server.sin_addr.s_addr=inet_addr(ip);
if(bind(sock,(struct sockaddr*)&server,sizeof(server))<0)
{
perror("bind\n");
exit(4);
}
if(listen(sock,10)<0)
{
perror("listen\n");
exit(5);
}
return sock;
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
Usage(argv[0]);
exit(1);
}
int listen_sock=startup(argv[1],atoi(argv[2]));
printf("fd:%d\n",listen_sock);
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
int newsock=accept(listen_sock,(struct sockaddr*)&client,&len);
if(newsock<0)
{
perror("accept\n");
continue;
}
printf("get a new client :%s %d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
char buf[1024];
while(1)
{
ssize_t s=read(newsock,buf,sizeof(buf)-1);
if(s<0)
{
perror("read\n");
exit(6);
}
if(s==0)
{
printf("client quit\n");
exit(7);
}
else
{
buf[s]=0;
printf("client say:%s\n",buf);
write(newsock,buf,sizeof(buf)-1) ;
}
}
close(newsock);
} close(listen_sock);
return 0;
}
//多进程版本
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
int startup(char*ip, int port)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock<0)
{
perror("socket");
exit(2);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (bind(sock, (struct sockaddr*)&server, sizeof(struct sockaddr_in))<0)
{
perror("bind");
exit(3);
}
if (listen(sock, 10)<0)
{
perror("listen");
exit(4);
}
return sock;
}
void usage(const char*proc)
{
printf("%s [local_ip] [local_port]\n", proc);
exit(5);
}
int main(int argc, char* argv[])
{
if(argc!=3)
{
usage(argv[0]);
}
int listen_sock = startup(argv[1], atoi(argv[2]));
printf("fd:%d\n", listen_sock);
while (1)
{
struct sockaddr_in client;
socklen_t len = sizeof(client);
int newsock = accept(listen_sock, (struct sockaddr*)&client, &len);
if (newsock<0)
{
perror("accept");
continue;
}
printf("get a client:[%s:%d]\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
pid_t id = fork();
if (id == 0)
{
close(listen_sock);
if (fork() == 0)
{
char buf[1024];
while (1)
{
ssize_t ret = read(newsock, buf, sizeof(buf)-1);
if (ret>0)
{
buf[ret] = 0;
printf("client say:%s\n", buf);
write(newsock, buf, sizeof(buf)-1);
}
else if (ret == 0)
{
printf("client quit!\n");
close(newsock);
exit(7);
}
else
{
perror("read");
exit(8);
}
}
}
else
{
exit(9);
}
}
else if (id>0)
{
close(newsock);
while((waitpid(-1,NULL,WNOHANG)>0));
continue;
}
else
{
perror("fork");
exit(9);
}
}
close(listen_sock);
return 0;
}
//多线程版本
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include <pthread.h>
void usage(char* proc)
{
printf("usage:%s [local_ip][local_port]\n",proc);
exit(2);
}
int startup(char* ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket\n");
exit(3);
}
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(port);
server.sin_addr.s_addr=inet_addr(ip);
if(bind(sock,(struct sockaddr*)&server,sizeof(server))<0)
{
perror("bind\n");
exit(4);
}
if(listen(sock,10)<0)
{
perror("listen\n");
exit(5);
}
return sock;
}
void* thread_handler(void* arg)
{
int newsock=*((int*)arg);
char buf[1024];
while(1)
{
ssize_t ret=read(newsock,buf,sizeof(buf)-1);
if(ret<0)
{
perror("read\n");
exit(8);
}
else if(ret==0)
{
printf("client quit\n");
exit(9);
}
else{
buf[ret]=0;
printf("client say:%s\n",buf);
write(newsock,buf,sizeof(buf)-1);
}
}
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
usage(argv[0]);
exit(1);
}
int listen_sock=startup(argv[1],atoi(argv[2]));
printf("fd:%d\n",listen_sock);
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
int newsock=accept(listen_sock,(struct sockaddr*)&client,&len);
if(newsock<0)
{
perror("accept\n");
exit(6);
}
printf("get a new client:[%s:%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
pthread_t tid;
int ret=pthread_create(&tid,NULL,thread_handler,&newsock);
if(ret<0)
{
perror("pthread_create\n");
exit(7);
}
pthread_detach(tid);
}
close(listen_sock);
return 0;
}
//client
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
void Usage(char* proc)
{
printf("Usage:%s[local_ip][local_port]\n",proc);
exit(2);
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
Usage(argv[0]);
exit(1);}
int sock=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_sock;
server_sock.sin_family=AF_INET;
server_sock.sin_port=htons(atoi(argv[2]));
server_sock.sin_addr.s_addr=inet_addr(argv[1]);
if(connect(sock,(struct sockaddr*)&server_sock,sizeof(server_sock))<0)
{
perror("connect\n");
exit(3);
}
while(1)
{
printf("please enter:");
fflush(stdout);
char buf[1024];
ssize_t ret=read(0,buf,sizeof(buf)-1);
if(ret>0)
{
buf[ret-1]=0;
write(sock,buf,sizeof(buf)-1);
read(sock,buf,sizeof(buf)-1);
printf("server say:%s\n",buf);
}
}
close(sock);
return 0;
}
server bind 失败的原因及解决方法?
client终⽌时⾃动关闭socket描述符,server的TCP连接收到client发的FIN段后处于TIME_WAIT状 态。TCP协议规定,主动关闭连接的一⽅要处于TIME_WAIT状态,等待两个MSL(maximum segment lifetime)的时间后才能回到CLOSED状态,因为我们先Ctrl-C终⽌了server,所以server是主动关闭连接的⼀⽅,在TIME_WAIT期间仍然不能再次监听同样的server端 ⼜口。MSL在RFC1122中规定为两分钟,但是各操作系统的实现不同,在Linux上一般经过半分钟后 就可以再次启动server了。解决这个问题的⽅法是使用setsockopt()设置socket描述符的 选项SO_REUSEADDR为1,表示允许创建端⼜口号相同但IP地址不同的多个socket描述符。即将其设置为非阻塞就可以。