zoukankan      html  css  js  c++  java
  • 基于TCP协议的网络通讯流程

    不多说了,先上个图:

    从上面的图中可以看出来,基于TCP协议进行通讯可以大致分成以下几个阶段:

    1. 首先是在服务器端, TCP Sever调用socket(), bind(), listen()完成初始化。然后调用accept()阻塞等待,处于监听端口的状态。

    2. 客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,

    同时应答一个ACK段,服务器收到后从accept()返回。这也就是传说中的TCP三次握手,如下图所示:

    TCP 三次握手有一种形象的理解,大家去买手机的时候总要试试手机的通话功能吧, 这时你会走远和你的朋友通话看看质量是否可靠,一般是不是这样:

    • 喂, 听的到吗? (Client)
    • 听的到, 你听的到吗 ? (Server)
    • 嗯, 我也听的到 (Client)

    那么就能保证通话质量是OK的, TCP协议也是一样, 通过规定了双方的应答保证了连接的可靠性。

    3. 完成三次握手(TCP three way handshake ) TCP Server与TCP Client就建立起了可靠的连接。此后就是Server与Client 数据传输的过程了。因此,服务器从accept()返回

    后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待,这时客户端调用write()发送请求给服务器,服务器收到后从read()返回,对客户端的请求进行处理,在

    此期间客户端调用read()阻塞等待服务器的应答,服务器调用write()将处理结果发回给客户端,再次调用read()阻塞等待下一条请求,客户端收到后从read()返回,发送下一条请

    求,如此循环下去。

    4. 关闭连接的过程。 如果客户端没有更多的请求了,就调用close()关闭连接,就像写端关闭的管道一样,服务器的read()返回0,这样服务器就知道客户端关闭了连接,也调用

    close()关闭连接。注意,任何一方调用close()后,连接的两个传输方向都关闭,不能再发送数据了。如果一方调用shutdown()则连接处于半关闭状态,仍可接收对方发来的数

    据。

     贴一个简易的TCP Sever与TCP Client的实现:

     1 /***********************************************************/
     2 /* Copyright (C) SA14226214, USTC, 2014-2015               */
     3 /*                                                         */
     4 /*  FILE NAME             :  server.c                      */
     5 /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
     6 /*  SUBSYSTEM NAME        :  lab1                          */
     7 /*  MODULE NAME           :  server                        */
     8 /*  LANGUAGE              :  C                             */
     9 /*  TARGET ENVIRONMENT    :  ANY                           */
    10 /*  DATE OF FIRST RELEASE :  2014/12/01                    */
    11 /*  DESCRIPTION           :  This is a server program      */
    12 /***********************************************************/
    13 
    14 /*
    15  *Revision log:
    16  *
    17  *Ceated by GaoZhipeng, 2014/12/01
    18  *     
    19  */
    20 
    21 #include<stdio.h>
    22 #include<stdlib.h>
    23 #include<string.h>
    24 #include<unistd.h>
    25 #include<sys/socket.h>
    26 #include<netinet/in.h>
    27 
    28 #define MAXLINE 80
    29 #define SERV_PORT 8000
    30 
    31 int main(void) 
    32 {
    33     struct sockaddr_in servaddr, cliaddr;
    34     socklen_t cliaddr_len;
    35     int listenfd, connfd;
    36     char recv_buf[MAXLINE];
    37     char *send_buf;
    38     char str[INET_ADDRSTRLEN];
    39     int i, n;
    40 
    41     listenfd = socket(AF_INET, SOCK_STREAM, 0);
    42 
    43     bzero(&servaddr, sizeof(servaddr));
    44     servaddr.sin_family = AF_INET;
    45     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    46     servaddr.sin_port = htons(SERV_PORT);
    47 
    48     bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    49     listen(listenfd,20);
    50 
    51     printf("Accepting connections ...
    ");
    52     cliaddr_len = sizeof(cliaddr);
    53     connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
    54     while(1)
    55     {
    56         n = read(connfd, recv_buf, MAXLINE);
    57         if(n == 0)
    58         {
    59             printf("the client has been closed , please restart again
    ");
    60             break;
    61         }
    62         printf("received from %s at PORT %d ",(char *)inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
    63 //print the recv_buf on the terminal
    64         write(STDOUT_FILENO, recv_buf, n);
    65         printf("
    ");
    66 
    67         send_buf = "你好世界";
    68         write(connfd, send_buf, strlen(send_buf));
    69     }
    70     close(connfd);
    71 
    72 }
     1 /***********************************************************/
     2 /* Copyright (C) SA14226214, USTC, 2014-2015               */
     3 /*                                                         */
     4 /*  FILE NAME             :  server.c                      */
     5 /*  PRINCIPAL AUTHOR      :  GaoZhipeng                    */
     6 /*  SUBSYSTEM NAME        :  lab1                          */
     7 /*  MODULE NAME           :  server                        */
     8 /*  LANGUAGE              :  C                             */
     9 /*  TARGET ENVIRONMENT    :  ANY                           */
    10 /*  DATE OF FIRST RELEASE :  2014/12/01                    */
    11 /*  DESCRIPTION           :  This is a server program      */
    12 /***********************************************************/
    13 
    14 /*
    15  *Revision log:
    16  *
    17  *Ceated by GaoZhipeng, 2014/12/01
    18  *     
    19  */
    20 
    21 #include<stdio.h>
    22 #include<stdlib.h>
    23 #include<string.h>
    24 #include<unistd.h>
    25 #include<sys/socket.h>
    26 #include<netinet/in.h>
    27 
    28 #define MAXLINE 80
    29 #define SERV_PORT 8000
    30 
    31 int main(int argc, char *argv[]) 
    32 {
    33     struct sockaddr_in servaddr;
    34     char buf[MAXLINE];
    35     int sockfd, n;
    36 
    37     sockfd = socket(AF_INET, SOCK_STREAM, 0);
    38 
    39     bzero(&servaddr, sizeof(servaddr));
    40     servaddr.sin_family = AF_INET;
    41     inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
    42     servaddr.sin_port = htons(SERV_PORT);
    43 
    44     connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    45 
    46     printf("input you message (q to exit): ");
    47 
    48     //ŽÓ±ê׌ÊäÈëÉ豞ÖжÁÈ¡×Ö·ûŽ®ÐŽÈëbuf
    49     while(fgets(buf, MAXLINE, stdin) != NULL) {
    50         if(buf[0] == 'q' && strlen(buf) == 2)
    51         {
    52             break;
    53         }
    54         write(sockfd, buf, strlen(buf));
    55 
    56         n = read(sockfd, buf, MAXLINE);
    57         if(n == 0)
    58         {
    59             printf("the connect side has been closed. please run it again
    ");
    60             exit(0);
    61         }
    62         write(STDOUT_FILENO, "Response from server : ", sizeof("Response from server : "));
    63         write(STDOUT_FILENO, buf, n);
    64         printf("
    input you message (q to exit): ");
    65     }
    66     close(sockfd);
    67     return 0;
    68 }

    一个简单的MakeFile :

    /*           makefile               */
    all :
            gcc server.c -o server
            gcc client.c -o client
    
    clean :
            rm server client
  • 相关阅读:
    ThinkPHP第二十天(getField用法、常用管理员表结构、树形结构前小图标CSS)
    ThinkPHP第十九天(Ueditor高亮插件、扩展函数载入load、静态缓存)
    Bootstrap第一天
    ThinkPHP第十八天(Widget类的使用,连贯操作where IN用法,缓存S函数使用)
    ThinkPHP第十七天(隐藏index.php和简短路径配置)
    ThinkPHP第十六天(redirect、join、视图模型)
    ThinkPHP第十五天(setField、setInc、setDec、关联模型)
    ThinkPHP第十四天(显示TRACE界面配置,关联模型详解定义)
    ThinkPHP第十三天(CONF_PATH、APP_PATH,UEditor用法)
    ThinkPHP常量参考
  • 原文地址:https://www.cnblogs.com/beyond-Acm/p/4365345.html
Copyright © 2011-2022 走看看