多线程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("接收数据错误");
    }
 
}
原文地址:https://www.cnblogs.com/tianyake/p/4522039.html