socket编程

1、服务端

//socket_sv.c

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

int main(int argc, char* argv){

    //1.creat linsten socket
    int lfd = socket(AF_INET, SOCK_STREAM,0);
    if (lfd == -1)
    {
        perror("socket");
        exit(0);
    }
    //2.bind lfd to local ip address and port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(10000);

    int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));

    if (ret == -1){
        perror("bind");
        exit(0);
    }

    //3,listen
    ret = listen(lfd, 128);
    if (ret == -1)
    {
        perror("listen");
        exit(0);
    }

    //3.accept and block wait client connect
    struct sockaddr_in cliaddr;
    int addrlen = sizeof(cliaddr);
    int cfd = accept(lfd, (struct sockaddr *)&cliaddr,&addrlen);
    if (cfd == -1)
    {
        perror("accept");
        exit(0);
    }

    //4.print client information
    char ip[24] = {0};
    printf("client ip addres: %s, port: %d\n", 
    inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));
    
    //5.recv and send message with client
    while (1)
    {
        char buf[1024];
        memset(buf,0 ,sizeof(buf));
        int len = read(cfd, buf,sizeof(buf));
        if (len > 0)
        {
            printf("recv from client: %s\n",buf);
            write(cfd, buf, len);
        }else if(len == 0){
            printf("client disconnect...\n");
            break;
        }else{
            perror("read");
            break;
        }     
    }
    close(cfd);
    close(lfd);
    return 0;
}

2、客户端

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

int main(int argc, char* argv){

    //1.creat communcation socket
    int fd = socket(AF_INET, SOCK_STREAM,0);
    if (fd == -1)
    {
        perror("socket");
        exit(0);
    }
    //2.connect server
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    inet_pton(AF_INET,"localhost",&addr.sin_addr.s_addr);
    addr.sin_port = htons(10000);

    int ret = connect(fd,(struct sockaddr *)&addr,sizeof(addr));

    if (ret == -1){
        perror("connect");
        exit(0);
    }
    
    //3. communication with server
    int number = 0;
    while (1)
    {
        char buf[1024];
        sprintf(buf, "hello socket...%d\n",number++);
        write(fd, buf,strlen(buf)+ 1);


        // recv form server
        memset(buf,0,sizeof(buf));
        int len = read(fd, buf, sizeof(buf));

        if (len > 0)
        {
            printf("recv from server: %s\n",buf);
        }else if(len == 0){
            printf("server disconnect...\n");
            break;
        }else{
            perror("read");
            break;
        }
        sleep(1);    
    }
    close(fd);
    return 0;
}

3、多进程实现服务端并发

//socket_sv1.c
//mutiple process concurrency server
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void callback(int num){
    while(1){
        pid_t pid = waitpid(-1, NULL, WNOHANG);
        if (pid <= 0)
        {
            printf("chind process is running or had been collect.\n");
            break;
        }
        printf("child die, pid = %d\n", pid);     
    }
}

int childWork(int cfd){
    char buf[1024];
    memset(buf, 0, sizeof(buf));
    int len = read(cfd ,buf,sizeof(buf));
    if (len > 0)
    {
        printf("recv form cliet: %s\n", buf);
        write(cfd, buf,len);
    }else if(len == 0){
        printf("client disconnect...\n");
    }else{
        perror("read");
    }       
    return len;
}


int main(int argc, char* argv){

    //1.creat linsten socket
    int lfd = socket(AF_INET, SOCK_STREAM,0);
    if (lfd == -1)
    {
        perror("socket");
        exit(0);
    }
    //2.bind lfd to local ip address and port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(10000);

    int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));

    if (ret == -1){
        perror("bind");
        exit(0);
    }

    //3,listen
    ret = listen(lfd, 128);
    if (ret == -1)
    {
        perror("listen");
        exit(0);
    }

    //regesist signal
    struct sigaction act;
    act.sa_flags = 0;
    act.sa_handler = callback;
    sigemptyset(&act.sa_mask);
    sigaction(SIGCHLD,&act, NULL);
    while (1)
    {
        //block and wait client connect
        struct sockaddr_in cliaddr;
        int clilen = sizeof(cliaddr);
        int cfd = accept(lfd, (struct sockaddr* )&cliaddr, &clilen);
        if (cfd == -1){
            if(errno ==EINTR){
                //accept interupp by signal, relese block, return -1
                //call one times again
                continue;
            }
            perror("accept");
            exit(0);
        }
         //print client information
        char ip[24] = {0};
        printf("client ip addres: %s, port: %d\n", 
        inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));

        //creat child process connect
        pid_t pid = fork();
        if (pid == 0){
            close(lfd);
            while (1)
            {
               int ret = childWork(cfd);
               if  (ret <= 0){
                break;
               }
            }
            close(cfd);
            exit(0);
            
        }else if(pid > 0){
            close(cfd);
        }   
    }    
    return 0;
}

4、多线程实现服务端并发

//socket_sv2.c
//pthread concurrency server
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct SockInfo{
    int fd;
    pthread_t tid;
    struct sockaddr_in addr;
};
struct SockInfo infos[128];

void *working(void* arg){
    while (1)
    {
       struct SockInfo* info = (struct SocInfo*) arg;
       // recv data
       char buf[1024];
       int ret = read(info->fd,buf,sizeof(buf));
       if(ret == 0){
        printf("client disconnect...\n");
        break;
       }else if(ret == -1){
        printf("recv data fail...\n");
        info->fd = -1;
        break;
       }else{
        write(info->fd,buf,strlen(buf) +1);
       }
    }
    return NULL;
    
}

int main(int argc, char* argv){

    //1.creat linsten socket
    int fd = socket(AF_INET, SOCK_STREAM,0);
    if (fd == -1)
    {
        perror("socket");
        exit(0);
    }
    //2.bind lfd to local ip address and port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(10000);

    int ret = bind(fd,(struct sockaddr *)&addr,sizeof(addr));

    if (ret == -1){
        perror("bind");
        exit(0);
    }

    //3,listen
    ret = listen(fd, 128);
    if (ret == -1)
    {
        perror("listen");
        exit(0);
    }

    //4.wait client connect request
    int len = sizeof(struct sockaddr);

    // init
    int max = sizeof(infos)/sizeof(infos[0]);
    for (int i = 0; i < max; i++)
    {
        bzero(&infos[i],sizeof(infos[0]));
        infos[i].fd = -1;
        infos[i].tid = -1;
    }

    //parent listen and child communicate
    while (1)
    {
        struct SockInfo* pinfo;
        for (int i = 0; i < max; i++)
        {
            if (infos[i].fd == -1){
                pinfo = &infos[i];
                break;
            }
            if(i == max -1){
                sleep(1);
                i--;
            }
        }

        int connfd = accept(fd, (struct sockaddr *)&pinfo->addr,&len);
        printf("parent thread connfd: %d\n", connfd);
        if (connfd == -1)
        {
            perror("accept");
            exit(0);
        }
        pinfo->fd = connfd;
        pthread_create(&pinfo->tid,NULL,working,pinfo);   
    }
    
    return 0;
}

5、select IO 多路复用实现并发

//socket_sv3.c
//select IO mulputile concurrency
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char* argv){

    //1.creat linsten socket
    int lfd = socket(AF_INET, SOCK_STREAM,0);
    if (lfd == -1)
    {
        perror("socket");
        exit(0);
    }
    //2.bind lfd to local ip address and port
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(10000);

    int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));

    if (ret == -1){
        perror("bind");
        exit(0);
    }

    //3,listen
    ret = listen(lfd, 128);
    if (ret == -1)
    {
        perror("listen");
        exit(0);
    }

    //transform lfd state chenck  task to kernel

    int maxfd = lfd;

    //init rfd set
    fd_set rdset;
    fd_set rdtemp;
    //zero 
    FD_ZERO(&rdset);
    //set lfd to rdset
    FD_SET(lfd, &rdset);

    while (1)
    {
        rdtemp = rdset;
        int num = select(maxfd+1, &rdtemp,NULL,NULL,NULL);
        //check is data in read buf, when rdset index equal 1, and buf have data
        if (FD_ISSET(lfd,&rdtemp)){
            //have data in read buf, and accept will not block
            struct sockaddr_in cliaddr;
            int addrlen = sizeof(cliaddr);
            int cfd = accept(lfd, (struct sockaddr *)&cliaddr,&addrlen);
            if (cfd == -1)
            {
                perror("accept");
                exit(0);
            }
              //print client information
            char ip[24] = {0};
            printf("client ip addres: %s, port: %d\n", 
            inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));
            // add communicate fd to rdset , can dectect cfd in next cycle
            FD_SET(cfd, &rdset);

            //reset max fd
            maxfd = cfd > maxfd? cfd: maxfd;
        }
        for (int i = 0; i < maxfd + 1; i++)
        {
            if (i != lfd && FD_ISSET(i, &rdtemp)){
                //recv data
                char buf[1024];
                memset(buf,0 ,sizeof(buf));
                int len = read(i, buf,sizeof(buf));
                if (len > 0)
                {
                    //send data
                    printf("recv from client: %s\n",buf);
                    write(i, buf, len);
                }else if(len == 0){
                    printf("client disconnect...\n");
                    //delete dected fd from read fd set
                    FD_CLR(i, &rdset);
                    close(i);
                }else{
                    perror("read");
                }                    
            }
        }       
    }
    close(lfd);
    return 0;
}

你可能感兴趣的:(c++,udp,c语言)