UDP特点:无连接,不提供可靠传输服务,不提供流量控制,不提供拥塞控制
但是UDP相对TCP也有着自己独特的优势
UDP和TCP在套接字数量上面的区别:
在TCP中,套接字之间是一对一的关系,若向十个客户端提供服务,就要创建10个套接字,而在UDP中,无论是客户端还是服务器端都是主要提供一个套接字。
UDP套接字不会维护连接状态,所以每次发送数据包都需要添加目标主机和端口
未连接套接字就是每次都变更地址
已连接套接字就是向目标主机注册地址,多次发送数据包地址不变
#include <winsock2.h> int sendto(SOCKET s,const char* buf,int len,int flags,const struct sockaddr* to,int tolen);
#include <winsock2.h> int recvfrom(SOCKET s,const char* buf,int len,int flags,const struct sockaddr* from,int fromlen);
基于windows的回声服务器端和苦户端
/*client.c*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #define BUF_SIZE 30 void ErrorHanding(char *message); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET sock; char message[BUF_SIZE]; int strLen; SOCKADDR_IN servAdr; if(argc!=3){ printf("Usage:%s <IP> <Port>\n",argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) ErrorHanding("WSAStartup() error!"); sock = socket(PF_INET,SOCK_DGRAM,0); if(sock==INVALID_SOCKET) ErrorHanding("scoket() error!"); memset(&servAdr,0,sizeof(servAdr)); servAdr.sin_family=AF_INET; servAdr.sin_addr.s_addr=inet_addr(argv[1]); servAdr.sin_port=htons(atoi(argv[2])); connect(sock,(SOCKADDR*)&servAdr,sizeof(servAdr)); while(1){ fputs("Insert message(q to quit):",stdout); fgets(message,sizeof(message),stdin); if(!strcmp(message,"q\n")||!strcmp(message,"Q\n")) break; send(sock,message,strlen(message),0); strLen=recv(sock,message,sizeof(message)-1,0); message[strLen]=0; printf("message from sever:%s",message); } closesocket(sock); WSACleanup(); return 0; } void ErrorHanding(char* message){ fputs(message,stderr); fputs("\n",stderr); exit(1); }
/*server.c*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #define BUF_SIZE 30 void ErrorHanding(char *message); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET servSock; char message[BUF_SIZE]; int strLen; int clntAdeSz; SOCKADDR_IN servAdr,clntAdr; if(argc!=2){ printf("Usage:%s <port>\n",argv[0]); exit(1); } if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) ErrorHanding("WSAStartup() Error!"); servSock = socket(PF_INET,SOCK_DGRAM,0); if(servSock == INVALID_SOCKET) ErrorHanding("UDP CREATE SOCKET ERROR!"); memset(&servAdr,0,sizeof(servAdr)); servAdr.sin_family=AF_INET; servAdr.sin_addr.s_addr=htonl(INADDR_ANY); servAdr.sin_port=htons(atoi(argv[1])); if(bind(servSock,(SOCKADDR*)&servAdr,sizeof(servAdr))==SOCKET_ERROR) ErrorHanding("bind() Error!"); while(1){ clntAdeSz=sizeof(clntAdr); strLen=recvfrom(servSock,message,BUF_SIZE,0,(SOCKADDR*)&clntAdr,&clntAdeSz); sendto(servSock,message,strLen,0,(SOCKADDR*)&clntAdr,sizeof(clntAdr)); } closesocket(servSock); WSACleanup(); return 0; } void ErrorHanding(char* message){ fputs(message,stderr); fputs("\n",stderr); exit(1); }