美文网首页
网络通信一1-11

网络通信一1-11

作者: 赋闲 | 来源:发表于2017-02-20 11:19 被阅读0次
    // 实现一个简单的回射服务器
    // 将客户端发送来的数据发扬回弹
    // 要求服务器绑定的IP和端口从命令行参数读入
    // ./echo_server <server_ip> <server_port>
    
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <arpa/inet.h>
    //服务器
    #define N 200
    
    int main(int argc, char *argv[])
    {
        if(argc != 3)
        {
            printf("usage : %s <server_ip> <server_port>\n", argv[0]);
            return 1;
        }
            
        char buf[N] = {'\0'};
        int n = 0;
        int sock_fd = 0;
    
        // 1.使用socket函数创建流式监听socket对象用于进行网络通信
        // int socket(int domain, int type, int protocol);
        // 参数:
        // domain   地址族,用于说明套接字的具体用途,AF_INET
        // type     套接字类型,SOCK_STREAM,SOCK_DGRAM
        // protocal 指定协议类型,常为0
        // 返回值:成功,返回流式套接字的描述符;失败,-1
        if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            perror("socket failed");
            return 1;
        }
        printf("sock_fd = %d\n", sock_fd);
        
        // 2.使用bind函数为监听套接字绑定众所周知的IP和端口
        // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
        // 参数:
        // sockfd   待绑定地址信息的套接字的描述符
        // sockaddr 待绑定的地址结构体的起始地址
        // addrlen  待绑定的地址结构体的大小
        // 返回值:成功,返回0;失败,返回-1
        struct sockaddr_in serveraddr;
        
        memset(&serveraddr, 0, sizeof(serveraddr));
        // 指定地址族,必须跟监听套接字的地址族类型一致
        serveraddr.sin_family = AF_INET;
        // IP地址
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        // serveraddr.sin_addr.s_addr = INADDR_ANY;
        // 端口号
        serveraddr.sin_port = htons(atoi(argv[2]));
        
        if(bind(sock_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
        {
            printf("bind failed");
            return 2;
        }
        
        // 3.使用listen函数改变监听套接字的状态
        // int listen(int sockfd, int backlog);
        // 参数:
        // sockfd   待改变状态的套接字描述符
        // backlog  等待连接的队列长度
        // 返回值:成功,返回0;失败,-1
        listen(sock_fd, 10);
        
        // 4.循环接受客户端的连接请求,并对其进行服务
        // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        // 参数:
        // sockfd   监听套接字的描述符
        // addr     用于接收客户端的连接地址
        // addrlen  客户端地址的长度,在调用accept函数之前,必须有长度值,调用完成之后,传出一个实际长度值
        // 返回值:成功,返回连接套接字的描述符;失败,返回-1
        struct sockaddr_in clientaddr;
        socklen_t len = 0;
        
        while(1)
        {
            printf("waiting for someone connection...\n");
            memset(&clientaddr, 0, sizeof(clientaddr));
            len = sizeof(clientaddr);
            int conn_fd = accept(sock_fd, (struct sockaddr *)&clientaddr, &len);
            
            printf("connection with %s : %d\n", inet_ntoa(clientaddr.sin_addr),
            ntohs(clientaddr.sin_port));
             
            // 与客户端进行数据通信
            while(1)
            {
                // 接收客户端发送来的数据
                n = recv(conn_fd, buf, N, 0);
                
                if(strncmp(buf, ".exit", 5) == 0)
                    break;
                    
                // 数据处理
                
                // 向客户端发送结果数据    
                send(conn_fd, buf, n, 0);
            }
            
            printf("client %s : %d exit!!!\n", inet_ntoa(clientaddr.sin_addr),
                ntohs(clientaddr.sin_port));
            
            close(conn_fd);
        }
        
        close(sock_fd);
    
        return 0;
    }```
    
    ```c
    // 回射服务器客户端
    // 从键盘读入数据,将读入的数据发送给服务器,然后接收服务器回弹的数据
    // 服务器的IP和端口从服务器读入
    // ./echo_client <server_ip> <server_port>
    
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    //客户端
    #define N 200
    
    int main(int argc, char *argv[])
    {
        if(argc != 3)
        {
            printf("usage : %s <server_ip> <server_port>\n", argv[0]);
            return 1;
        }
    
        char buf[N] = {'\0'};
        int n = 0;
        
        // 1.socket
        int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
        
        // 2.connect
        struct sockaddr_in serveraddr;
        
        memset(&serveraddr, 0, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));
        if(connect(sock_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
        {
            perror("connect failed");
            return 1;
        }
            
        // 3.read/write
        // 循环从键盘读入数据,发送给服务器端,当输入.exit时,客户端退出
        while(1)
        {
            // 3.1从键盘读入数据
            write(STDOUT_FILENO, ">", 1);
            n = read(STDIN_FILENO, buf, N);
            
            // 3.2将读入的数据发送给服务器
            // ssize_t send(int sockfd, const void *buf, size_t len, int flags);
            // 参数:
            // sockfd   使用sockfd所关联的套接字发送数据
            // buf      待发送数据的起始地址
            // len      待发送数据的字节长度
            // flags    发送方式
            // 返回值:实际发送成功的字节数
            send(sock_fd, buf, n, 0);
            
            // 当从键盘读入的数据为.exit时,客户端退出
            if(strncmp(buf, ".exit", 5) == 0)
                break;
    
            // 3.3接收从服务器回弹的数据病打印
            // size_t recv(int sockfd, void *buf, size_t len, int flags);
            // 参数:
            // sockfd   从sockfd所关联的套接字中接收数据
            // buf      存放接收数据的空间的起始地址
            // len      存放空间的最大字节数
            // flags    接收方式
            n = recv(sock_fd, buf, N, 0);
            printf("echo from server : \n");
            write(STDOUT_FILENO, buf, n);
        }
        
        printf("client exit, bye!!!\n");
        
        // close
        close(sock_fd);
        return 0;
    }
    
    // 使用流式套接字的服务器
    
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <arpa/inet.h>
    #define N 200
    int main(int argc, char *argv[])
    {
        int sock_fd = 0;
        char buf[N]={'\0'};
    
        // 1.使用socket函数创建流式监听socket对象用于进行网络通信
        // int socket(int domain, int type, int protocol);
        // 参数:
        // domain   地址族,用于说明套接字的具体用途,AF_INET
        // type     套接字类型,SOCK_STREAM,SOCK_DGRAM
        // protocal 指定协议类型,常为0
        // 返回值:成功,返回流式套接字的描述符;失败,-1
        if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            perror("socket failed");
            return 1;
        }
        printf("sock_fd = %d\n", sock_fd);
        
        // 2.使用bind函数为监听套接字绑定众所周知的IP和端口
        // int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
        // 参数:
        // sockfd   待绑定地址信息的套接字的描述符
        // sockaddr 待绑定的地址结构体的起始地址
        // addrlen  待绑定的地址结构体的大小
        // 返回值:成功,返回0;失败,返回-1
        struct sockaddr_in serveraddr;
        
        memset(&serveraddr, 0, sizeof(serveraddr));
        // 指定地址族,必须跟监听套接字的地址族类型一致
        serveraddr.sin_family = AF_INET;
        // IP地址
        serveraddr.sin_addr.s_addr = inet_addr("10.211.55.3");
        // serveraddr.sin_addr.s_addr = INADDR_ANY;
        // 端口号
        serveraddr.sin_port = htons(8888);
      /*  //客户端
        if(connect(sock_fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) == -1)
        {
        perror("connect failed");
        return 1;
        }
        int n = read
        */
        
        if(bind(sock_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
        {
            printf("bind failed");
            return 2;
        }
        
        // 3.使用listen函数改变监听套接字的状态
        // int listen(int sockfd, int backlog);
        // 参数:
        // sockfd   待改变状态的套接字描述符
        // backlog  等待连接的队列长度
        // 返回值:成功,返回0;失败,-1
        listen(sock_fd, 10);
        
        // 4.循环接受客户端的连接请求,并对其进行服务
        // int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        // 参数:
        // sockfd   监听套接字的描述符
        // addr     用于接收客户端的连接地址
        // addrlen  客户端地址的长度,在调用accept函数之前,必须有长度值,调用完成之后,传出一个实际长度值
        // 返回值:成功,返回连接套接字的描述符;失败,返回-1
        while(1)
        {
            printf("waiting for someone connection...\n");
            int conn_fd = accept(sock_fd, NULL, NULL);
            
            // 与客户端进行数据通信
            write(conn_fd, "wo ai beijing tian'an men!!!", 100);
            
            close(conn_fd);
        }
            
        close(sock_fd);
            
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:网络通信一1-11

          本文链接:https://www.haomeiwen.com/subject/fjkfwttx.html