• Linux网络编程4——个人总结


    TCP与UDP通信流程

    TCP通信的基本步骤如下:

    服务端:socket---bind---listen---while(1){---accept---recv---send---close---}------close

    客户端:socket------------------------------connect---send---recv-----------------close

    UDP通信的基本步骤如下:

    服务端:socket---bind---recvfrom---sendto----close

    客户端:socket----------sendto----recvfrom---close

    函数原型

    TCP

    TCP
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    server:
    
    int socket(int domain, int type, int protocol);
    
    int bind(int fd_server, struct sockaddr *addr_server, int addrlen); /* 绑定服务器联系方式,让客户端有明确的联系方式可以连接 */
    
    int listen(int fd_server, int backlog); /* 将fd_server转换为被动套接字,同时内核将listen到的请求的联系方式放入队列 */
    
    int accept(int fd_server, struct sockaddr *addr_client, int *addrlen); /* 返回客户端socket的另一端,以此建立连线 *//* addr_client为传出参数,存放请求连接方的联系方式 ,如不需要刻意置为NULL */
    
    client:
    
    int connect (int fd_client,struct sockaddr *addr_server, int addrlen); /* 通过服务器的联系方式addr_server去连接服务器 */
    
    /* 作为服务器,一定要绑定联系方式,不然请求方没有明确的联系方式可以连接 ,
       作为客户端,可以不用绑定联系方式,其端口号会由系统自动分配。          
       建立连线的关键在于accept函数会返回客户端socket描述符所对应的另一端socket的描述符,
       并且客户端的联系方式也可以在accept中使用传出函数获取。                              */
       
    after connect:
    
    /* 建立连线后,就可以利用socket描述符发送接收信息了 */
    int recv(int sockfd,void *buf,int len,unsigned int flags);
    
    int send(int s,const void * msg,int len,unsigned int flags);
    
    /* 会话结束,关闭 */
    int close(int fd);

    UDP

    UDP
    
    server:
    
    int socket(int domain, int type, int protocol);
    
    /* 绑定服务器联系方式,让客户端有明确的联系方式可以连接 */
    int bind(int fd_server, struct sockaddr *addr_server, int addrlen); 
    
    /* 由于fd_server已经绑定联系方式(addr_server),请求方发送信息时,会通过addr_server发送消息至服务器fd_server,
       因此,服务器可以通过fd_server收到消息,并且请求方的联系方式可以通过传出参数addr_client获取                */
    int recvfrom(int fd_server, void *buf, int len, unsigned int flags, struct sockaddr *addr_client, int *addrlen); 
    
    /* 请求方的联系方式(addr_client)会由系统自己绑定,服务器是通过recvfrom的传出参数获取addr_client的。
       因此服务器发送消息时,可以通过客户端联系方式addr_client发送至客户端fd_client。                  */
    int sendto(int fd_server, const void *msg, int len, unsigned int flags, const struct sockaddr *addr_client, int addrlen);
    
    client:
    
    /* 客户端的联系方式,服务器可以在recvfrom时获取,因此没有必要在一开始就绑定 */
    int sendto(int fd_server, const void *msg, int len, unsigned int flags, const struct sockaddr *addr_client, int addrlen);
    
    int recvfrom(int fd_server, void *buf, int len, unsigned int flags, struct sockaddr *addr_client, int *addrlen); 
    
    /* 实际上,UTP通信方式并没有建立socket连线,双方均是通过联系方式(IP和端口号)进行通信的。
       服务器需要在一开始绑定联系方式,不然请求方没有明确的联系方式可以连接。
       当服务器recvfrom,不但可以收到客户端的消息,同时可以获取客户端的联系方式。            */

    总结

    1. TCP通信会建立连线。服务器的socket端口会bind联系方式,给客户端一个明确的联系方式去connect。服务器会listen到客户端的connect,并将其联系方式放入内核维护的任务请求队列中。之后服务器accept,获取与客户端通信的对应socket端口,从而建立连线!之后双方通过socket端口进行通信。

    2. UDP通信不会建立连线。服务器的socket端口同样会bind联系方式。客户端通过此联系方式向服务器发送(sendto)消息,由于此联系方式已绑定到服务器的socket端口,因此服务器一定可以收到(recvfrom)消息,与此同时通过recvfrom的传出参数获取客户端的联系方式,从而可以通过客户端的联系方式向客户端发送消息。即,UTP的通信是基于联系方式(IP和端口号)的。是不可靠的通信方式。

    3. 为什么TCP中的accept与UDP中的recvfrom都可以通过传出参数获取对方联系方式?不理解的话,可以类比寄信,别人给你寄一封信时,总会写上自己的联系方式吧。

  • 相关阅读:
    表单
    超链接
    图像
    表格
    排列清单控制标
    HTML基本结构
    如何快速查看网页源代码
    TOR的使用
    google搜索新姿势
    [NOIP2017]列队
  • 原文地址:https://www.cnblogs.com/jianxinzhou/p/3945795.html
Copyright © 2020-2023  润新知