Linux c++(socket网络通信 & 多线程服务器)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <unistd.h>


#include <pthread.h>
#include <arpa/inet.h>

using namespace std;

typedef struct SockInfo{
    int fd;
    struct sockaddr_in addr;
    socklen_t addr_len;
    pthread_t id;
}SockInfo;
void* 
pthread_Callback(void* arg);

int main(int argc, char *argv[])                                                         
{
    if(argc < 2)           
    {
        printf("err: ./app port\n");
        exit(1);
    }
    int port = atoi(argv[1]);
    // 创建套接字
    int lfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in serv_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_port = htons(port);
    serv_addr.sin_family = AF_INET;
    socklen_t serv_len = sizeof(serv_addr);
    int ret;
    if((ret =bind(lfd,(struct sockaddr*)&serv_addr,serv_len)) != 0){
        perror("err: bind");
        exit(1);
    }
    if((ret =listen(lfd,36))!=0)
    {
        perror("err: listen");
        exit(2);
    }

    printf("Start accept\n");


    // 设置线程属性
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

    SockInfo info[256];
    for (int j=0;j<sizeof(info)/sizeof(SockInfo);++j)
        info[j].fd = -1;

    int i;
    while(1)
    {
        for (i=0;i<sizeof(info)/sizeof(SockInfo);++i)
        {
            if(info[i].fd == -1)   
                break;
        }
        if(i == 256)
            break;

        struct sockaddr_in cli_addr;
        socklen_t cli_len = sizeof(cli_addr);

        // 主线程等待接收连接请求
        info[i].fd =accept(lfd,(struct sockaddr*)&cli_addr,&cli_len); 

        info[i].addr = cli_addr;
        info[i].addr_len = cli_len;


        // 创建子线程通讯
        pthread_t tid;
        pthread_create(&tid,&attr,pthread_Callback,&info[i]);

    }
    close(lfd);
    pthread_attr_destroy(&attr);
    pthread_exit(NULL);
    return 0;
}

void* 
pthread_Callback(void* arg){
    SockInfo *info = (SockInfo*)arg;
    while(1)
    {
        char ip[64]={0};                                                                 

        char buf[1024];
        printf("New Client IP: %s, Port: %d\n",
               inet_ntop(AF_INET,&info->addr.sin_addr.s_addr,ip,sizeof(ip)),
               ntohs(info->addr.sin_port));
        int len = read(info->fd,buf,sizeof(buf));
        if(len == -1)
        {
            perror("read err");
            pthread_exit(NULL);
        }else if(len == 0)
        {
            printf("客户端断开连接\n");
            close(info->fd);
            break;
        }else{
            printf("recv: %s\n",buf);
            write(info->fd,buf,len);
        }
    }
    pthread_exit(NULL);
}

client

#include <iostream>

#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>

using namespace std;

int main(int argc, char *argv[])                                                         
{
    if(argc != 2)
    {
        printf("exe: app port\n");
        exit(1);
    }

    int lfd = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in cli_addr;
    memset(&cli_addr,0,sizeof(cli_addr));
    cli_addr.sin_family = AF_INET;
    cli_addr.sin_port = htons(0);

    if(bind(lfd,(struct sockaddr*)&cli_addr,sizeof(cli_addr)))
    {
        printf("Create Socket Failed!\n");
        exit(1);
    }

    struct sockaddr_in serv;
    serv.sin_family = AF_INET;
    serv.sin_port = htons(atoi(argv[1]));
    inet_pton(AF_INET,"127.0.0.1",&(serv.sin_addr.s_addr));
    if(connect(lfd,(struct sockaddr*)&serv,sizeof(serv)))
    {
        printf("Can Not Connect To %s!\n",argv[1]);
        exit(1);
    }

    char buf[1024] = {0};
    while(1)
    {
        // c 刷新缓冲区
        //fflush(stdin);
        // c++ 刷新缓冲区
        //cin.sync();

        //string str;
        //getline(cin,str);
        //cout<<str<<endl;
        //send(lfd,str.c_str(),str.length(),0);
        fgets(buf,sizeof(buf),stdin);
        send(lfd,buf,sizeof(buf),0);
        recv(lfd,buf,sizeof(buf),0);
    }
    return 0;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM