| win操作系统C++语言 socket,udp通信本文用于记录win操作系统,C++语言,socket,udp通信 服务端流程首先要加载套接字库 创建套接字服务端地址bind 套接字与地址绑定recvfrom 等待并接收数据sendto 发送数据资源关闭
 服务端代码示例// udpsrv.cpp 
#include<stdio.h>
#include <iostream>
#include <WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
	WORD wVersionRequested;//unsigned short 
	WSADATA wsaData;//这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据
	int err;
	wVersionRequested = MAKEWORD(1,1);
    //WSAStartup就是为了向操作系统说明,我们要用哪个库文件,让该库文件与当前的应用程序绑定,从而就可以调用该版本的socket的各种函数了
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		return -1;
	}
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)//低字节为主版本,高字节为副版本
	{
		WSACleanup();
		return -1;
	}
//.......以上为准备环境....以下为具体服务端udp通讯流程..........
	std::cout << "server is operating!\n\n";
	//1.创建套接字
	SOCKET socketSrv = socket(AF_INET, SOCK_DGRAM, 0);
	//2.服务端地址
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", (void *)&addrSrv.sin_addr.S_un.S_addr);
	addrSrv.sin_port = htons(6000);
	//3.套接字绑定
	bind(socketSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	SOCKADDR_IN addrClient;//用来接收客户端地址信息
	char ClientIP[20];
	int len = sizeof(SOCKADDR);
	char recvBuf[100];
	char sendBuf[100];
	char tempBuf[100];
	while (1)
	{
		//4.等待并接收数据
		recvfrom(socketSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);
		if ('q' == recvBuf[0])
		{
			sendto(socketSrv, "q", strlen("q") + 1, 0, (SOCKADDR*)&addrClient, len);
			std::cout << "chat end!\n\n";
			break;
		}
		inet_ntop(AF_INET, (void *)&addrClient.sin_addr, ClientIP, 16);
		sprintf_s(tempBuf, "%s say : %s", ClientIP, recvBuf);
		printf("%s\n",tempBuf);
		
		//5.发送数据
		std::cout << "Please input data:";
		gets_s(sendBuf);
		sendto(socketSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrClient, len);
	}
    //6.关闭资源
	closesocket(socketSrv);
	WSACleanup();
    return 0;
}
 客户端流程首先要加载套接字库 创建用于监听的套接字确定服务端通讯地址信息sendto 发送数据recvfrom 等待并接收数据资源关闭
 // udpclient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<stdio.h>
#include<WinSock2.h>
#include<WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
	//加载套接字库
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(1, 1);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		return -1;
	}
	if (LOBYTE(wsaData.wVersion) != 1 ||     //低字节为主版本
		HIBYTE(wsaData.wVersion) != 1)      //高字节为副版本
	{
		WSACleanup();
		return -1;
	}
	printf("Client is operating!\n\n");
	//1.创建用于监听的套接字
	SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
    
    //2.确定服务端通讯地址信息
	sockaddr_in  addrSrv;
	inet_pton(AF_INET, "127.0.0.1", (void *)&addrSrv.sin_addr.S_un.S_addr);
	//addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//输入你想通信的她(此处是本机内部)
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	int len = sizeof(SOCKADDR);
	char recvBuf[100];    //收
	char sendBuf[100];    //发
	char tempBuf[100];    //存储中间信息数据
	while (1)
	{
		printf("Please input data: ");
		gets_s(sendBuf);
        //3.发送数据
		sendto(sockSrv, sendBuf, strlen(sendBuf) + 1, 0, (SOCKADDR*)&addrSrv, len);
		//4.等待数据
		recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrSrv, &len);
		if ('q' == recvBuf[0])
		{
			sendto(sockSrv, "q", strlen("q") + 1, 0, (SOCKADDR*)&addrSrv, len);
			printf("Chat end!\n");
			break;
		}
		sprintf_s(tempBuf, "%s say : %s", "server", recvBuf);
		printf("%s\n", tempBuf);
	}
	closesocket(sockSrv);
	WSACleanup();
	return 0;
}
 遇到的问题 错误:error C4996: ‘inet_addr’: Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings 原因:在VS2013以后的版本中,增加了inet_pton()、InetPton()之类的新函数,用于IP地址在“点分十进制”和“二进制整数”之间转换,并且能够处理ipv4和ipv6。而inet_addr是老函数,高版本VS在编译时默认使用了新函数,所以会报该错误。 解决办法: inet_pton(AF_INET, "127.0.0.1", (void *)&addrSrv.sin_addr.S_un.S_addr);
//addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//输入你想通信的她(此处是本机内部)
 错误:C4996 ‘inet_ntoa’: Use inet_ntop() or InetNtop() instead or define 原因:同上 解决办法: inet_ntop(AF_INET, (void *)&addrClient.sin_addr, ClientIP, 16);
 错误LNK2019: 无法解析的外部符号 _WSAStartup@8,该符号在函数 _main 中被引用
 原因:编译器没有链接到我们想要的头文件运行库 解决办法:#pragam 编译器指令,指示编译器链接到<winsock.h>的库文件ws2_32.lib,即**#pragma comment(lib,“ws2_32.lib”)** #pragma comment(lib,"ws2_32.lib")
 问题总结第一类问题是主机字节序列与网络字节序列转换函数的版本问题 第二类是编译问题 程序运行效果图
 |