文章目录
- 客户端
- 流程
- 代码实现
- 添加头文件以及库依赖
- 加载库
- 创建套接字
- 发送接收数据
- 关闭套接字、卸载库
- 测试
客户端
流程
客户端跟服务端差不多,也要先加载库,在加载库之后也要创建套接字,但是客户端一定是没有绑定ip地址的,之后是循环发送数据和接收数据,最后关闭套接字、卸载库。
不需要绑定ip地址是因为绑定ip地址是在操作系统那里注册,那么为什么客户端不需要绑定而服务端就要绑定呢,原因是有发送数据的顺序决定的,一般都是客户端先发,主动发消息的时候操作系统就会自动给分配一个端口号,然后操作系统也会帮助选择一个网卡
代码实现
添加头文件以及库依赖
#include<iostream>
#include<WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
加载库
int err = 0;
WORD version = MAKEWORD(2, 2);
WSADATA wsaData;
err = WSAStartup(version,&wsaData);
if (0 != err) {
cout << "WSAStartup error" << endl;
return 1;
}
if (2 != HIBYTE(wsaData.wVersion) || 2 != LOBYTE(wsaData.wVersion)) {
cout << "WSAStartuo version error" << endl;
WSACleanup();
return 1;
}
else {
cout << "WSAStart success" << endl;
}
创建套接字
//创建套接字
SOCKET sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (INVALID_SOCKET == sock) {
cout << "socket error" << endl;
WSACleanup();
return 1;
}
else {
cout << "socket success" << endl;
}
发送接收数据
因为我们要发给服务端,并且服务端在自己的设备上,所以我们需要创建一个sockaddr_in结构体,然后写入IP地址类型、端口号与ip地址
IP地址类型就是ipv4类型AF_INET,端口号需要填写在服务端绑定的端口号,因为服务端只能接收来自那个端口号的数据包,ip地址就填本机ip地址就可以,注意要用inet_addr()将字符串类型转为ulong类型
因为我们已知对端的ip,所以在接收数据的时候不需要使用输出参数,填NULL即可
while (true) {
//发送数据
char msg[] = "xixix";
nSendNum = sendto(sock,msg,sizeof(msg),0, (sockaddr*)&addrServer,addrServerSize);
if (SOCKET_ERROR == nSendNum) {
cout << "sendto error:" << WSAGetLastError() << endl;
break;
}
//接收数据
nRecvNum = recvfrom(sock, recvBuf, sizeof(recvBuf), 0, NULL, NULL);
if (nRecvNum > 0) {
cout << "say:" << recvBuf << endl;
}
else {
cout << "recvfrom error:" << WSAGetLastError() << endl;
break;
}
}
关闭套接字、卸载库
closesocket(sock);
WSACleanup();
最后不要忘记在项目属性中关闭SDL检查
测试
运行一下,先开启服务端再开启客户端
没有问题!