多线程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测试在发送的时候会带一个\n不能直接通过strcmp来比,所以写了下面的程序来处理

int isExit(char *s1)

{

    if(strlen(s1)<6)

    {

        return 0;

    }

    char const *str="quit";

    while(*str!='\0')

    {

        if(*str-*s1==0)

        {

        }

        else {

            printf("不同的是:%c,%c\n",*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\n",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 = "恭喜你成功连接到本服务器\n";

    write(sock , message , strlen(message));

    while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )

    {

        client_message[read_size]='\0';

        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("接收数据错误");

    }

 

}

 

你可能感兴趣的:(多线程)