UDP协议

//#pragma once

//UDP协议
//https://blog.csdn.net/xxbsky520/article/details/6161217

#include <winsock2.h>
#pragma comment(lib, "WS2_32")//https://www.cnblogs.com/wyj553/archive/2009/04/16/1437512.html
#include <iostream>
using namespace std;


int main()
{
	SOCKET sock;   //socket套接字
	char szMsg[] = "this is a UDP test package";//被发送的字段

	//1.启动SOCKET库,版本为2.0
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 0);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (0 != err) //检查Socket初始化是否成功
	{
		cout << "Socket2.0初始化失败,Exit!";
		return 0;
	}

	//检查Socket库的版本是否为2.0
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
	{
		WSACleanup();
		return 0;
	}

	//2.创建socket,
	sock = socket(
		AF_INET,           //internetwork: UDP, TCP, etc
		SOCK_DGRAM,        //SOCK_DGRAM说明是UDP类型
		0                  //protocol
	);

	if (INVALID_SOCKET == sock) {
		cout << "Socket 创建失败,Exit!";
		return 0;
	}

	//3.设置该套接字为广播类型,
	bool opt = true;
	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char FAR *>(&opt), sizeof(opt));

	//4.设置发往的地址
	sockaddr_in addrto;            //发往的地址 
	memset(&addrto, 0, sizeof(addrto));
	addrto.sin_family = AF_INET;               //地址类型为internetwork
	addrto.sin_addr.s_addr = INADDR_BROADCAST; //设置ip为广播地址
	addrto.sin_port = htons(7861);             //端口号为7861

	int nlen = sizeof(addrto);
	unsigned int uIndex = 1;
	while (uIndex < 10)//true
	{
		Sleep(1000); //程序休眠一秒

	    //向广播地址发送消息
		/*7.12           sendto函数
		在Socket中有两套发送和接收函数,一是sendto和recvfrom;二是send和recv。前一套在函数参数中要指明地址;而后一套需要先将套接字和一个地址绑定,然后直接发送和接收,不需绑定地址。
		sendto的定义如下:
		int PASCAL FAR sendto(SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen);
		第一个参数就是套接字;
		第二个参数是要传送的数据指针;
		第三个参数是要传送的数据长度(字节数);
		第四个参数是传送方式的标识,如果不需要特殊要求则可以设置为0,其它值请参考MSDN;
		第五个参数是目标地址,注意这里使用的是sockaddr的指针;
		第六个参数是地址的长度;
		返回值为整型,如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR。*/

		if (sendto(sock, szMsg, strlen(szMsg), 0, (sockaddr*)&addrto, nlen)
			== SOCKET_ERROR)
			cout << WSAGetLastError() << endl;
		else
			cout << uIndex++ << ":an UDP package is sended." << endl;
	}

	if (!closesocket(sock)) //关闭套接字
	{
		WSAGetLastError();
		return 0;
	}
	if (!WSACleanup())       //关闭Socket库
	{
		WSAGetLastError();
		return 0;
	}
	return 0;
}

VS2017下成功运行

参考:

https://blog.csdn.net/xxbsky520/article/details/6161217

https://www.cnblogs.com/wyj553/archive/2009/04/16/1437512.html

下面是完整例子

服务端:

#include <winsock2.h>
#include <iostream>
#pragma comment(lib, "WS2_32")

using namespace std;

int main()
{
	//1.启动SOCKET库,版本为2.0
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 0);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		cout << "Socket2.0初始化失败,Exit!";
		return 0;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
	{
		WSACleanup();
		return 0;
	}

	//2.创建套接字
	SOCKET sock;
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
	{
		cout << "Socket 创建失败,Exit!";
		return 0;
	}

	//3.绑定
	SOCKADDR_IN myaddr; //sockaddr_in相当于sockaddr结构
	memset(&myaddr, 0, sizeof(myaddr));//初始化  清零 
	myaddr.sin_family = AF_INET;//只能为这个值
	//如果绑定地址不是本机地址或者ADDR_ANY,则recvfrom函数不会正确接收,而是立刻返回
	myaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将u_long型转换为网络字节序列
	//端口号必须和客户发往的端口号一致
	myaddr.sin_port = htons(7861);//将u_short型转换为网络字节序列
	bind(sock, (SOCKADDR*)&myaddr, sizeof(myaddr));//绑定套接字

	//4.等待并接受数据
	SOCKADDR_IN addrClient;
	int len = sizeof(SOCKADDR);
	char buf[256] = "";
	long number = 0;
	while (true) {
		Sleep(1000);
		number++;
		//recv(sock, buf, sizeof(buf), 0);
		recvfrom(sock, buf,256,0,(SOCKADDR*)&addrClient, &len);
		cout << number << ":" << buf << endl;
		memset(buf, 0, sizeof(buf));

		if (number > 5)break;
	}

	//??这两个条件?
	//if (!closesocket(sock))
	//{
	//	WSAGetLastError();
	//	return 0;
	//}
	//if (!WSACleanup())
	//{
	//	WSAGetLastError();
	//	return 0;
	//}

	cout << "服务器关闭" << endl;
	closesocket(sock);
	WSACleanup();
	return 0;
}


客户端:

#include <winsock2.h>
#pragma comment(lib, "WS2_32")
#include <iostream>

using namespace std;

int main()
{
	//1.启动SOCKET库,版本为2.0
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 0);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		cout << "Socket2.0初始化失败,Exit!";
		return 0;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0)
	{
		WSACleanup();
		return 0;
	}

	//2.创建socket,
	SOCKET sock;                   //socket
	sock = socket(
		AF_INET,           //internetwork: UDP, TCP, etc
		SOCK_DGRAM,        //SOCK_DGRAM说明是UDP类型
		0                  //protocol
	);

	if (sock == INVALID_SOCKET) {
		cout << "Socket 创建失败,Exit!";
		return 0;
	}

	//3.设置发往的地址
	SOCKADDR_IN addrto;            //发往的地址	
	memset(&addrto, 0, sizeof(addrto));
	addrto.sin_family = AF_INET;

	// https://jingyan.baidu.com/article/1709ad8041dca64634c4f006.html
	//去掉SDL检查。设置项目属性,将c/c++->SDL检查设置为“否”即可跳过检查,使用旧的函数可编译成功。
	addrto.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //旧函数,不设置sdl检查会报错

	//端口号必须和服务器绑定的端口号一致
	addrto.sin_port = htons(7861);

	//4.发送消息
	int nlen = sizeof(addrto);
	unsigned int uIndex = 1;
	char szMsg[] = "this is a UDP test package";//被发送的字段
	while (true)
	{
		Sleep(1000);
		if (sendto(sock, szMsg, strlen(szMsg), 0, (SOCKADDR*)&addrto, nlen)
			== SOCKET_ERROR)
			cout << WSAGetLastError() << endl;
		else
			cout << uIndex++ << ":an UDP package is sended." << endl;

		if (uIndex > 10)break;
	}

	//if (!closesocket(sock))
	//{
	//	WSAGetLastError();
	//	return 0;
	//}
	//if (!WSACleanup())
	//{
	//	WSAGetLastError();
	//	return 0;
	//}


	cout << "客户端关闭" << endl;
	closesocket(sock);
	WSACleanup();
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值