1,一般情况下,TCP比UDP慢,原因通常有以下两点:
(1)收发数据前后进行的连接设置及清除过程;
(2)收发过程中为保证可靠性而添加的流控制;
所以,如果发送的都是短消息,要求能及时响应,并且对安全性和稳定性要求不高的情况下使用UDP。
2,UDP服务端与客户端均只需1个套接字。
3,未连接的UDP套接字不会保持连接状态,每次收发数据都要提供对方的IP地址和端口号。
4,UDP客户端程序(如PC与PLC通信时,PLC的IP和端口固定,所以一般PC为客户端)
int sock;
char message[BUFF_SIZE];
int str_len;
socklen_t adr_sz;
struct sockaddr_in serv_adr,from_adr;
if(argc!=3){
printf("Usage : %s <IP><port>\n",argv[0]);
exit(1);
}
sock = socket(PF_INET,SOCK_DGRAM,0);
memset(&serv_adr, 0 , sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
serv_adr.sin_port = htons(atoi(argv[2]));
while(1)
{
sendto(sock,message,strlen(message),0,(struct sockaddr*)&from_adr,sizeof(serv_adr));
adr_sz = sizeof(from_adr);
str_len = recvfrom(sock,message,BUF_SIZE,0,(struct sockaddr*)&from_adr,&adr_sz);
message[str_len] = 0;
printf("Message from server: %s", message);
}
close(sock);
return 0;
注意:UDP服务器端要采用bind函数把serv_sock和serv_adr进行绑定,因为他是被动连接,客户端向服务器发消息,必须知道服务器的网络地址,但是客户端可以不用绑定ip和port号(如上图程序中没有bind函数),因为 当客户端调用sendto函数时发现sock尚未分配地址信息,则在首次调用sendto函数时会给相应套接字自动分配ip和端口号,而且此时分配的地址一直保留到程序结束为止。(TCP中,客户端通过调用connect函数自动分配ip和端口号给套接字)。
5,UDP称为未连接套接字。Why
sendto函数传输数据过程分为三个阶段:
(1)向UDP套接字注册目标ip和端口号
(2)传输数据
(3)删除UDP套接字中注册的目标地址信息
所以可以利用同一个UDP套接字对不同的目标地址传输信息。若要与同一主机进行长时间通信,则将未连接的UDP套接字变成连接套接字会提高效率(需要调用connect函数)。
6,sendto函数和recvfrom函数调用次数必须保持一致