tcp_server

来源:互联网 发布:优化关键词技巧 编辑:程序博客网 时间:2024/06/07 17:16
//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描述符。即将其设置为非阻塞就可以。

原创粉丝点击