zoukankan      html  css  js  c++  java
  • linux: TCP和UDP的不同

    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都可以通过传出参数获取对方联系方式?不理解的话,可以类比寄信,别人给你寄一封信时,总会写上自己的联系方式吧。

  • 相关阅读:
    Study Plan The TwentySecond Day
    Study Plan The Nineteenth Day
    Study Plan The TwentySeventh Day
    Study Plan The Twentieth Day
    Study Plan The TwentyFirst Day
    python实现进程的三种方式及其区别
    yum makecache
    JSONPath 表达式的使用
    oracle执行cmd的实现方法
    php daodb插入、更新与删除数据
  • 原文地址:https://www.cnblogs.com/DLzhang/p/3985192.html
Copyright © 2011-2022 走看看