利用Winsock实现UDP通信

UDP通信的定义

Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。

Winsock用于通信的结构体

首先认识几个Windows提供的结构体:
WORD:为微软SDK中的类型,为两个Byte的无符号整数,可用MAKEWORD函数生成,语句为WORD Wrd = MAKEWORD(bLow,bHigh);
SOCKET: 用于创建socket,可作为数据的接收端或发出端
SOCKADDR_IN:该结构体指定了地址族(sin_family), 16位TCP/UDP端口号(sin_port),32位IP地址(sin_addr),与保留的字符数组char sin_zeros[8]

服务端socket建立

1.调用WSAStartup函数,启动Windows Sockets Asynchronous,即Windos异步嵌套字,完成Winsock服务初始化。
2.调用socket函数建立服务端socket,参数指明为UDP通信。
sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3.将该socket与SOCKADDR_IN类型的数据变量通过bind函数绑定,该变量指定了socket的地址族、端口号与IP地址。

服务端程序源码

int socket_init()
{
    if (WSAStartup(wVersionRequested, &wsaData) != 0) {
        printf("WSAStartup failed\n");
        return -1;
    }

    sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);               //采用UDP

    if (sServer == INVALID_SOCKET) {
        printf("socket establish failed\n");
        return -1;
    }

    addrServ.sin_family = AF_INET;
    addrServ.sin_port = htons(9990);                          //相同的端口响应相同端口的请求
    addrServ.sin_addr.S_un.S_addr = htons(INADDR_ANY);

    retVal = bind(sServer, (const sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
    
    if (retVal == SOCKET_ERROR) {
        printf("bind failed\n");
        closesocket(sServer);
        WSACleanup();
        return -1;
    }

      return 0;
  }

用户端socket建立

1.同样调用WSAStartup函数,完成Winsock服务初始化。
2.调用socket函数建立服务端socket,参数指明为UDP通信。
sHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3.指明与该socket(sHost)进行数据交换socket的地址,即需要定义一个SOCKADDR_IN类型的变量,指定服务端的地址族、端口号与IP地址

用户端程序源码

int socket_init() {
	if (WSAStartup(wVersionRequested, &wsaData) != 0) {
		printf("WSAStartup failed\n");
		return -1;
	}
	
	sHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);              //UDP
	
	if (sHost == INVALID_SOCKET) {
		printf("socket establish failed\n");
		WSACleanup();
		return -1;
	}

	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(9990);
	addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	
	int sServerAddrLen = sizeof(addrServ);

	return 0;
}

信息的接收与发送

在WinSock实现的UDP通信中,我们通过sendto与recvfrom函数实现信息的发送与接收。

 int sendto ( socket s , const void * msg, int len, unsigned int flags, const
  struct sockaddr * to , int tolen ) ;

在该函数中,s为信息发送端,msg为信息首地址,len为长度,flags一般设为0,to指定接收信息的socket地址信息,tolen为地址信息的长度。

int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);

recvfrom函数的参数与sendto基本相同,同样需要指明发送信息的socket,接受信息的socket地址信息。

UDP通信的特点

1.UDP通信是无连接的传输层协议,这通过其调用sendto与recvfrom函数时需要指定接收方就可以看出。
2.UDP尽最大努力传输数据,但不能保证可靠交付。
3.UDP传输相对较快,且支持一对一、一对多、多对多的交互通信.

  • 30
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值