• TCP通讯模型简单示例


    1. TCP通讯模型

    2. 服务器端

    ① 创建socket,用函数socket()

    ② 绑定IP地址、端口号等信息到socket上,用函数bind()

    ③ 设置允许的最大连接数,用函数listen()

    ④ 等待来自客户端的连接请求,用函数accept()

    ⑤ 收发数据,用函数send()和recv(),或者read()和write()

    ⑥ 关闭网络连接,用函数close()

    3. 客户端

    ① 创建一个socket,用函数socket()

    ② 设置要连接的服务器的IP地址和端口的属性

    ③ 连接服务器,用函数connect()

    ④ 收发数据,用函数send()和recv(),或者read()和write()

    ⑤ 关闭网络连接,用函数close()

    4. 简单示例

    ① 服务器端

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <errno.h> 
    #include <string.h> 
    #include <netdb.h> 
    #include <sys/types.h> 
    #include <netinet/in.h> 
    #include <sys/socket.h> 
    
    #define portnumber 3333
    
    int main(int argc, char *argv[]) 
    { 
        int sockfd, new_fd; 
        struct sockaddr_in server_addr; 
        struct sockaddr_in client_addr; 
        int sin_size; 
        int nbytes;
        char buffer[1024];
        
        /* 服务程序建立sockfd描述符 */ 
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)                 // AF_INET:IPV4;SOCK_STREAM:TCP
        { 
            fprintf(stderr, "Socket error:%s
    a", strerror(errno)); 
            exit(1); 
        } 
    
        bzero(&server_addr, sizeof(struct sockaddr_in));                     // 初始化,置0
        
        server_addr.sin_family = AF_INET;                                     // Internet
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);                      // (将本机器上的long数据转化为网络上的long数据)服务器程序能运行在任何ip的主机上
                                                                            //INADDR_ANY 表示主机可以是任意IP地址,即服务器程序可以绑定到所有的IP上
        //server_addr.sin_addr.s_addr=inet_addr("192.168.1.1");              //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip
        
        server_addr.sin_port = htons(portnumber);                             // (将本机器上的short数据转化为网络上的short数据)端口号
        
        /* 捆绑sockfd描述符到IP地址 */ 
        if(bind(sockfd,(struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) 
        { 
            fprintf(stderr, "Bind error:%s
    a", strerror(errno)); 
            exit(1); 
        } 
    
        /* 设置允许连接的最大客户端数 */ 
        if(listen(sockfd, 5) == -1) 
        { 
            fprintf(stderr, "Listen error:%s
    a", strerror(errno)); 
            exit(1); 
        } 
    
        while(1) 
        { 
            /* 服务器阻塞,直到客户程序建立连接 */ 
            sin_size = sizeof(struct sockaddr_in); 
            if((new_fd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size)) == -1) 
            { 
                fprintf(stderr,"Accept error:%s
    a",strerror(errno)); 
                exit(1); 
            } 
    
            fprintf(stderr, "Server get connection from %s
    ", inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串
            if((nbytes = read(new_fd, buffer, 1024)) == -1) 
            { 
                fprintf(stderr, "Read Error:%s
    ", strerror(errno)); 
                exit(1); 
            }         
            
            buffer[nbytes] = '';
            printf("Server received %s
    ",buffer);
            
            /* 这个通讯已经结束 */ 
            close(new_fd); 
            /* 循环下一个 */ 
        } 
    
        /* 结束通讯 */ 
        close(sockfd); 
        exit(0); 
    } 

    ② 客户端

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <errno.h> 
    #include <string.h> 
    #include <netdb.h> 
    #include <sys/types.h> 
    #include <netinet/in.h> 
    #include <sys/socket.h> 
    
    #define portnumber 3333
    
    int main(int argc, char *argv[]) 
    { 
        int sockfd; 
        char buffer[1024]; 
        struct sockaddr_in server_addr; 
        struct hostent *host; 
    
        if(argc != 2) 
        { 
            fprintf(stderr, "Usage:%s hostname a
    ", argv[0]); 
            exit(1); 
        } 
    
        /* 使用hostname查询host名字 */
        if((host = gethostbyname(argv[1])) == NULL) 
        { 
            fprintf(stderr, "Gethostname error
    "); 
            exit(1); 
        } 
    
        /* 客户程序建立sockfd描述符 */ 
        if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) // AF_INET:Internet;SOCK_STREAM:TCP
        { 
            fprintf(stderr, "Socket Error:%sa
    ", strerror(errno)); 
            exit(1); 
        } 
    
        /* 客户程序填充服务端的资料 */ 
        bzero(&server_addr, sizeof(server_addr)); // 初始化,置0
    
        server_addr.sin_family = AF_INET;          // IPV4
        server_addr.sin_port = htons(portnumber);  // (将本机器上的short数据转化为网络上的short数据)端口号
        server_addr.sin_addr = *((struct in_addr *)host->h_addr); // IP地址
        
        printf("host->h_addr = 0x%x
    ", *((struct in_addr *)host->h_addr));
        printf("server_addr.sin_addr = 0x%x
    ", server_addr.sin_addr);
        
        
        /* 客户程序发起连接请求 */ 
        if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1) 
        { 
            fprintf(stderr, "Connect Error:%sa
    ", strerror(errno)); 
            exit(1); 
        } 
    
        /* 连接成功了 */ 
        printf("Please input char:
    ");
        
        /* 发送数据 */
        fgets(buffer, 1024, stdin);
        
        write(sockfd, buffer, strlen(buffer)); 
    
        /* 结束通讯 */ 
        close(sockfd); 
        exit(0); 
    } 
  • 相关阅读:
    设计一个字符串类,并将字符串处理函数的内容进行封装
    C++字符串处理函数【自写】
    文件共享服务器nfs搭建过程
    svn服务器的搭建过程 主要为服务端
    uwsgi和wsgi
    熟悉了下HTTP协议
    ModelForm views.py
    隐藏tomcat nginx版本信息
    csrf
    开发模式
  • 原文地址:https://www.cnblogs.com/wulei0630/p/9469276.html
Copyright © 2020-2023  润新知