zoukankan      html  css  js  c++  java
  • 多线程sockt服务器

    实现的功能是可以socket服务器允许多个客户端连接,连接到服务器的时候能够打印出连接的IP地址和端口,服务端连接到数据能够将客户端的IP地址和发送内容打印出来。

    效果:
    服务端

    appledeMacBook-Pro:聊天室 apple$ ./a.out 8888

    有一个远程机器连接到本机,ip地址:127.0.0.1,端口:40927

    分配句柄成功

    从客户端:127.0.0.1获取到数据vvv

    从客户端:127.0.0.1获取到数据0f

    从客户端:127.0.0.1获取到数据.test data


    客户端

    appledeMacBook-Pro:c++Primer apple$ telnet 127.0.0.1 8888

    Trying 127.0.0.1...

    Connected to localhost.

    Escape character is '^]'.

    恭喜你成功连接到本服务器

    vvv

    vvv

    0f    

    .0f

    test data

    .test data

    #include <stdio.h>
    
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <pthread.h>
    struct ClientInfo{
        int newsockfd;
        char* Ip;
    }clientInfo;
    void* connection_handler(void *);
    void error(const char *msg)
    {
        perror(msg);
        exit(1);
    }
    //因为是直接通过telent测试在发送的时候会带一个
    不能直接通过strcmp来比,所以写了下面的程序来处理
    int isExit(char *s1)
    {
        if(strlen(s1)<6)
        {
            return 0;
        }
        char const *str="quit";
        while(*str!='')
        {
            if(*str-*s1==0)
            {
            }
            else {
                printf("不同的是:%c,%c
    ",*str,*s1);
                return 0;
            }
            str++,s1++;
        }
        return 1;
    }
    int main(int argc, char const* argv[])
    {
        pthread_t thread_id;
        int sockfd,newsockfd,portno;
        socklen_t client;
        struct sockaddr_in serv_addr,cli_addr;
        int n;
        if(argc<2){
            fprintf(stderr,"请启动程序的时候输入一个正确的端口号");
            exit(1);
        }
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(sockfd<0)
        {
            error("打开Socket错误");
        }
        bzero((char *)&serv_addr,sizeof(serv_addr));
        portno=atoi(argv[1]);
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=INADDR_ANY;
        serv_addr.sin_port=htons(portno);
        if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
        {
            error("绑定端口错误");
        }
        listen(sockfd,5);
        client=sizeof(cli_addr);
        while((newsockfd=accept(sockfd,(struct sockaddr *)&cli_addr,&client)))
        {
            printf("有一个远程机器连接到本机,ip地址:%s,端口:%d
    ",inet_ntoa(cli_addr.sin_addr),cli_addr.sin_port);
            clientInfo.newsockfd=newsockfd;
            clientInfo.Ip=inet_ntoa(cli_addr.sin_addr);
             if( pthread_create( &thread_id , NULL ,  connection_handler , (void*) &clientInfo) < 0)
            {
                perror("创建线程失败");
                return 1;
            }
             puts("分配句柄成功");
        }
     
        if(newsockfd<0)
        {
            error("接受客户端请求失败");
        }
     
        close(newsockfd);
        close(sockfd);
        return 0;
    }
    void *connection_handler(void* arg)
    {
        ClientInfo *Client;
        Client=(struct ClientInfo*) arg;
        int sock=Client->newsockfd;
        char* c=Client->Ip;
        int read_size;
        char buffer[256];
        char *message , client_message[2000];
     
        //改善一个欢迎信息到客户端
        message = "恭喜你成功连接到本服务器
    ";
        write(sock , message , strlen(message));
        while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
        {
            client_message[read_size]='';
            printf("从客户端:%s获取到数据%s",c,client_message);
            write(sock,client_message,strlen(client_message));
            memset(client_message,0,2000);
        }
        if(read_size==0)
        {
            puts("客户端关闭");
        }
        else if(read_size==-1)
        {
            perror("接收数据错误");
        }
     
    }
  • 相关阅读:
    模拟登陆江西理工大学教务系统
    python3爬虫 -----华东交大校园新闻爬取与数据分析
    以selenium模拟登陆12306
    PAT (Basic Level) Practice (中文)1076 Wifi密码 (15 分)
    PAT (Basic Level) Practice (中文)1047 编程团体赛 (20 分)
    PAT (Basic Level) Practice (中文)1029 旧键盘 (20 分)
    PAT (Basic Level) Practice (中文)1016 部分A+B (15 分)
    PAT (Basic Level) Practice (中文)1031 查验身份证 (15 分)
    PAT (Basic Level) Practice (中文)1041 考试座位号 (15 分)
    PAT (Basic Level) Practice (中文)1037 在霍格沃茨找零钱 (20 分)
  • 原文地址:https://www.cnblogs.com/tianyake/p/4522039.html
Copyright © 2011-2022 走看看