返回列表 发新帖我要提问本帖赏金: 30.00元(功能说明)

[技术讨论] 结合W5500说一下网络通讯中的TCP与UDP

[复制链接]
800|0
 楼主| forgot 发表于 2023-2-8 15:36 | 显示全部楼层 |阅读模式
#申请原创#
  对于经典的OSI 参考模型将整个网络通信的功能划分为七层,从下到上依次为是物理层(PH)、数据链路层(DL)、网络层(N)、传输层(T)、会话层(S)、表示层(P)、应用层(A)。在TCP/IP协议中,将物理层数据链路层合并为网络接口层,将应用层、表示层、会话层被并为应用层,所以被简化为了四层。

  网络传输层主要是管理端到端之间的通信连接,其中包括有UDP协议和TCP协议,他们都属于TCP/IP的核心。在我们做嵌入式物联网产品设计的时候,就会遇到选择TCP还是选择UDP的问题。实际上两种通信各有各的特点。
TCP是面向连接的设计,当TCP客户端与服务端需要进行通讯时,首先需要向服务器申请建立TCP连接,连接过程包含三次握手,成功后才可以进行数据交互传输,三次握手连接既可以防止已经由历史连接,也可以避免多次握手造成资源浪费。

  而UDP是不需要进行连接的,只需要绑定对方的IP地址和端口,就可以进行数据发发送与接收。正式由于两种通讯方式的不同,导致两种方式各有优劣势。TCP因为有连接的存在,所以可以保证数据的正确性和数据的顺序,但是因为首部格式中包含了关键要素的字节表达,如端口、序号、确认号、等导致TCP首部固定字节有20个字节。而UDP通讯因为没有连接,所以并不能保证数据的正确性与完整性,是一种不可靠的传输方式,但是其首部固定字节只有8个,源端口、目的端口、长度、检验和各占2个。所以UDP在数据传输方面有速度会更快,延迟更低,实时性更好特点。

  以W5500套接字0进行UDP通讯为例,先进**的IP等配置和套接字0端口等参数初始化。在打开UDP套接字后,可以直接通过判断状态寄存器来接收数据,同样可以通过sendto();函数进行指定remote_ipremote_port后就可以发送数据。
  1.     while(1) {                                                                                                                                                                                                                        
  2.         switch(getSn_SR(0)) {
  3.         case SOCK_UDP:
  4.             if(getSn_IR(0) & Sn_IR_RECV) {
  5.                 setSn_IR(0, Sn_IR_RECV);
  6.             } else {
  7.                 sendto(0,buffer,50, remote_ip, remote_port);
  8.             }
  9.             break;
  10.         case SOCK_CLOSED:
  11.             close(0);
  12.             IINCHIP_WRITE( Sn_DPORT0(0),(uint8)((5000& 0xff00) >> 8));
  13.             IINCHIP_WRITE( Sn_DPORT1(0),(uint8)(5000 & 0x00ff));
  14.             IINCHIP_WRITE(Sn_MR(0),Sn_MR_UDP|Sn_MR_MULTI);
  15.             IINCHIP_WRITE( Sn_PORT0(0),(uint8)((5000 & 0xff00) >> 8));
  16.             IINCHIP_WRITE( Sn_PORT1(0),(uint8)(5000 & 0x00ff));
  17.             IINCHIP_WRITE( Sn_CR(0),Sn_CR_OPEN);
  18.             while( IINCHIP_READ(Sn_CR(0))) ;
  19.             break;        
  20.         }
  21.     }

  如果是以套接字0进行TCP通讯,在打开套接字自后,首先需要采用connect();函数对于指定remote_ipremote_port进行连接,当状态寄存器为SOCK_ESTABLISHED之后才可以获取接收的数据或者是通过send();函数进行发送数据。并且如果收到服务端的断开请求,应该进行套接字的关闭以进行下一次的打开和重新连接。
  1.     while(1) {
  2.         switch(getSn_SR(0)) {
  3.         case SOCK_INIT:
  4.             connect(0, remote_ip,remote_port);
  5.             break;
  6.         case SOCK_ESTABLISHED:
  7.             if(getSn_IR(0) & Sn_IR_CON) {
  8.                 setSn_IR(0, Sn_IR_CON);
  9.             }
  10.             len=getSn_RX_RSR(0);
  11.             if(len>0) {
  12.                 recv(0,buffer,len);
  13.                 send(0,buffer,len);
  14.             }
  15.             break;
  16.         case SOCK_CLOSE_WAIT:
  17.             close(0);
  18.             break;
  19.         case SOCK_CLOSED:
  20.             socket(0,Sn_MR_TCP,anyport++,Sn_MR_ND);
  21.             break;
  22.         }
  23.     }

  当然至于产品中到底选择是用UDP还是TCP需要根据实际通讯需求进行选择,一般要求占用资源小,响应快、能够接收数据不可靠的通讯系统中可以采用UDP。在资源充足,又需要保证数据可靠性的场合,需要用到TCP,如HTTP FTP等。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

打赏榜单

21ic小管家 打赏了 30.00 元 2023-03-13
理由:签约作者奖励

您需要登录后才可以回帖 登录 | 注册

本版积分规则

2112

主题

14683

帖子

59

粉丝
快速回复 在线客服 返回列表 返回顶部