TCP(循环服务器)---Linux

一、模型

服务器模型可以分:

        循环服务器:在同一时刻只能相应一个客户端的请求

        并发服务器:在同一时刻可以相应多个客户端的请求

二、基础的TCP循环服务器

服务器端:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


//ERRLOG的宏定义
#define ERRLOG(errmsg) do{\
            perror(errmsg);\
            printf("%s--%s--(%d)\n",__FILE__,__func__,__LINE__);\
            exit(-1);\
            }while(0)


int main(int argc,char *argv[])
{
    if(3!=argc)
    {
        printf("Usage: %s  \n",argv[0]);
    }
    
    //创建套接字
    int sockfd =0;
    if((sockfd=socked(AF_INET,SOCK_STREAM,0))==-1)
    {
        ERRLOG("socket error");
    }


    //填充服务器网络信息结构体
     struct sockaddr_in serveraddr;
     serveraddr.sin_family = AF_INET;
     serveraddr.sin_port = htons(atoi(argv[2]));
     serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

    //绑定套接字和网络信息结构体
    socklen_t addrlen =sizeof(serveraddr);
    if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen)==-1)
    {
        ERRLOG("bind error");
    }

    //将套接字设置成为被监听状态
    if(listen(sockfd,5)==-1)
    {
        ERRLOG("listen error");
    }

    //定义结构体来保护客户端的网络地址结构的结构体
    struct sockaddr_in clientaddr;
    socklen_t client_addrlen =sizeof(clientaddr);
    char buff[128]={0};
    int ret=0;

    //循环体
    while(1)
    {
        printf("正在等待客户端连接\n");
        int acceptfd=accept(sockfd,(struct sockaddr *)&clientaddr,&client_addrlen);
        if(acceptfd==-1)
        {
            ERRLOG("accept error");
        }
        
        printf("%s--%d 已经连接\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));



        while(1)
        {
            
            if(-1 == (ret = recv(acceptfd, buff, 128, 0)))
            {
                ERRLOG("recv error");
            }
            else if(0 == ret)
            {
                printf("客户端--%s(%d)--断开了连接\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
                break;
            }


            else if(!strcmp(buff, "quit"))
            {
                printf("客户端--%s(%d)--退出了\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
                break;
            }

            printf("%s(%d):%s\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port), buff);
            strcat(buff, "--nihao");
            send(acceptfd, buff, 128, 0);

        }
        
       close(acceptfd);

    }
    
    return 0;
}

客户端:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define ERRLOG(errmsg) do{\
                        perror(errmsg);\
                        printf("%s--%s--(%d)\n",__FILE__,__func__,__LINE__);\
                        exit(-1);\
                        }while(0)

int main(int argc, char *argv[])
{
    if(3 != argc)
    {
        printf("Usage: %s  \n", argv[0]);
        exit(-1);
    }

    //创建套接字
    int sockfd = 0;
    if(-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
    {
        ERRLOG("socket error");
    }
    

    //填充服务器网络信息结构体
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);


    //与服务器建立连接
    socklen_t addrlen = sizeof(serveraddr);
    if(-1 == connect(sockfd, (struct sockaddr *)&serveraddr, addrlen))
    {
        ERRLOG("connect error");
    }
    printf("与服务器连接成功\n");
    char buff[128] = {0};
    int ret = 0;

    //循环体
    while(1)
    {
        scanf("%s", buff);

        if(-1 == send(sockfd, buff, 128, 0))
        {
            ERRLOG("send error");
        }
        
        if(!strcmp(buff, "quit"))
        {
            break;
        }
        memset(buff, 0, 128);
       
        if(-1 == recv(sockfd, buff, 128, 0))
        {
            ERRLOG("recv error");
        }
        
        printf("recv: %s\n",buff);
    }
    close(sockfd);
    return 0;
}

三、实现TCP并发服务器的三种方法

多进程实现TCP并发服务器

多线程实现TCP并发服务器

IO多路复用实现TCP并发服务器

                                                                        华清远见学习笔记整理(3)

你可能感兴趣的:(网络编程问题集合,服务器,linux,tcp/ip)