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\n\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\n\a", strerror(errno)); 
        exit(1); 
    } 

    /* 设置允许连接的最大客户端数 */ 
    if(listen(sockfd, 5) == -1) 
    { 
        fprintf(stderr, "Listen error:%s\n\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\n\a",strerror(errno)); 
            exit(1); 
        } 

        fprintf(stderr, "Server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串
        if((nbytes = read(new_fd, buffer, 1024)) == -1) 
        { 
            fprintf(stderr, "Read Error:%s\n", strerror(errno)); 
            exit(1); 
        }         
        
        buffer[nbytes] = '\0';
        printf("Server received %s\n",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\n", argv[0]); 
        exit(1); 
    } 

    /* 使用hostname查询host名字 */
    if((host = gethostbyname(argv[1])) == NULL) 
    { 
        fprintf(stderr, "Gethostname error\n"); 
        exit(1); 
    } 

    /* 客户程序建立sockfd描述符 */ 
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) // AF_INET:Internet;SOCK_STREAM:TCP
    { 
        fprintf(stderr, "Socket Error:%s\a\n", 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\n", *((struct in_addr *)host->h_addr));
    printf("server_addr.sin_addr = 0x%x\n", server_addr.sin_addr);
    
    
    /* 客户程序发起连接请求 */ 
    if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))==-1) 
    { 
        fprintf(stderr, "Connect Error:%s\a\n", strerror(errno)); 
        exit(1); 
    } 

    /* 连接成功了 */ 
    printf("Please input char:\n");
    
    /* 发送数据 */
    fgets(buffer, 1024, stdin);
    
    write(sockfd, buffer, strlen(buffer)); 

    /* 结束通讯 */ 
    close(sockfd); 
    exit(0); 
} 

 

posted @ 2018-08-13 16:50  99度的水  阅读(360)  评论(0编辑  收藏  举报