UDP数据的接收

概要
Udp协议为非面向连接的协议,数据的发送与接收并不需要像TCP/IP协议那样事先建立连接,因此在数据发送速度及资源消耗表现上都胜于TCP/IP;但UDP为非可靠协议其发送(接收)数据并不一定能够保证对方能够正确的接收(发送),其可靠性需要另外的机制来实现。
 
发送端的实现用到的几个函数
1.        WSAStartup:启动Winsocket
2.        socket:创建Socket,参数指定为SOCK_DGRAM 接收包数据
3.        bind:设置用于接收数据的端口和地址
4.        recvfrom:从socket中接收数据
5.        closesocket:关闭socket
6.        WSACleanup:关闭Winsocket
 
与TCP/IP相比不需要调用的函数:
  1. listen :监听socket
  2. accept :接收客户端的请求
  3. 接收和发送的函数不一样tcp为 send/recv; udp为sendto/recvfrom
代码实现:

建立UDP服务端(接收端),它接收30次数据;接收包数据的最大长度为4096,超过此长度将会发生截断。

服务端:

#include "stdafx.h"  
#include <iostream>  
#include <WinSock2.h>  
#include <Windows.h>  
using namespace std;  


#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])  
{  
	WSAData wsd;           //初始化信息  
	SOCKET soRecv;              //接收SOCKET  
	char * pszRecv = NULL; //接收数据的数据缓冲区指针  
	int nRet = 0;  
	int i = 0;  
	int dwSendSize = 0;  
	SOCKADDR_IN siRemote,siLocal;    //远程发送机地址和本机接收机地址  

	//启动Winsock  
	if (WSAStartup(MAKEWORD(2,2),&wsd) != 0) {  
		cout << "WSAStartup Error = " << WSAGetLastError() << endl;  
		return 0;  
	}  

	//创建socket  
	soRecv = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);  
	if (soRecv == SOCKET_ERROR) {  
		cout << "socket Error = " << WSAGetLastError() << endl;  
		return 1;  
	}  

	//设置端口号  
	int nPort = 5150;  

	//int nPort = 1234;  
	siLocal.sin_family = AF_INET;  
	siLocal.sin_port = htons(nPort);  
	siLocal.sin_addr.s_addr = inet_addr("127.0.0.1");  

	//绑定本地地址到socket  
	if (bind(soRecv,(SOCKADDR*)&siLocal,sizeof(siLocal)) == SOCKET_ERROR) {  
		cout << "bind Error = " << WSAGetLastError() << endl;  
		return 1;  
	}  

	//申请内存  
	pszRecv = new char[4096];  
	if (pszRecv == NULL) {  
		cout << "pszRecv new char Error " << endl;  
		return 0;  
	}  

	for (int i = 0; i < 30; i ++){  
		dwSendSize = sizeof(siRemote);  
		//开始接受数据  
		nRet = recvfrom(soRecv,pszRecv,4096,0,(SOCKADDR*)&siRemote,&dwSendSize);  
		if (nRet == SOCKET_ERROR) {  
			cout << "recvfrom Error " << WSAGetLastError() << endl;  
			break;  
		}  
		else if (nRet == 0) {  
			break;  
		}  
		else{  
			pszRecv[nRet] = '\0';  
			cout << inet_ntoa(siRemote.sin_addr) << endl  
				<<pszRecv << endl;  
		}  

	}  
	//关闭socket连接  
	closesocket(soRecv);  
	delete[] pszRecv;  

	//清理  
	WSACleanup();  
	system("pause");
	return 0;  
}  

客户端:

#include "stdafx.h"  
#include <iostream>  
#include <WinSock2.h>  
#include <Windows.h>  
using namespace std;  


#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])  
{  
	WSAData wsd;           //初始化信息  
	SOCKET soSend;         //接收SOCKET  
	int nRet = 0;  
	int i = 0;  
	int dwSendSize = 0;  
	SOCKADDR_IN siLocal;    //远程发送机地址和本机接收机地址  

	//启动Winsock  
	if (WSAStartup(MAKEWORD(2,2),&wsd) != 0) {  
		cout << "WSAStartup Error = " << WSAGetLastError() << endl;  
		return 0;  
	}  

	//创建socket  
	soSend = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);  
	if (soSend == SOCKET_ERROR) {  
		cout << "socket Error = " << WSAGetLastError() << endl;  
		return 1;  
	}  

	//设置端口号  
	int nPort = 5150;  
	siLocal.sin_family = AF_INET;  
	siLocal.sin_port = htons(nPort);  
	siLocal.sin_addr.s_addr = inet_addr("127.0.0.1");  

	for (int i = 0; i < 30; i ++){  
		//开始接受数据  
		nRet = sendto(soSend,"123 mutouren",strlen("123 mutouren"),0,(SOCKADDR*)&siLocal,sizeof(SOCKADDR));  
		if (nRet == SOCKET_ERROR) {  
			cout << "sendto Error " << WSAGetLastError() << endl;  
			break;  
		}   
	}  
	//关闭socket连接  
	closesocket(soSend);  
	//清理  
	WSACleanup();  

	return 0;  
}  




  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值