UDP_Client
服务端与客户端的区别
服务端是先接收数据,数据有来的地址,需要告诉操作系统,进程使用哪个端口号,数据才能到达指定的端口。
先发送一个消息,才会有来源的端口号。源端口号和目的端口号必须不一样。
客户端不绑定端口号发送数据包,操作系统会在第一次发送消息的时候给客户端分配一个端口号,直到socket关闭。
如果能保证客户端每次都是先发送数据,可以不绑定端口号,如果有服务端先发送数据的情况,需要给客户端绑定一个端口号,以明确,发送端需要发往的地址。
代码书写
#include<iostream>
#include<Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
int main() {
//加载库
WORD version = MAKEWORD(2, 2);
WSADATA data;
int err = WSAStartup(version,&data);
if (0 != err) {
cout << "WSAStartup error" << endl;
return 1;
}
if (HIBYTE(data.wVersion) != 2 || LOBYTE(data.wVersion) != 2) {
cout << "verion wrong!" << endl;
WSACleanup();
return 1;
}
else {
cout << "WSAStartup success"<<endl;
}
//创建套接字
SOCKET sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (INVALID_SOCKET == sock) {
cout << "socket error" << WSAGetLastError()<<endl;
WSACleanup();
return 1;
}
else {
cout << "socket success" << endl;
}
//填写地址
char sendBUf[9999] = "";
char recvBuf[9999] = "";
int sendLen = sizeof(sendBUf);
int recvLen = sizeof(recvBuf);
sockaddr_in addrTo;
int addrToLen = sizeof(addrTo);
addrTo.sin_addr.S_un.S_addr = inet_addr(" 192.168.0.111");
addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(78910);//要发送给的进程的IP地址,端口号
while (true) {
//发送数据
gets_s(sendBUf);
int senNum = sendto(sock,sendBUf,sendLen,0,(sockaddr*) & addrTo,sizeof(addrTo));
if (SOCKET_ERROR == senNum) {
cout << "send error" << GetLastError() << endl;
break;
}
//接收数据
int recvNum = recvfrom(sock,recvBuf,recvLen,0,nullptr,nullptr);
//int recvNum = recvfrom(sock,recvBuf,recvLen,0,(sockaddr*)&addrTo,&addrToLen);
//后面两个输出参数可以不接(nullptr),发送接收方指定,不需要返回发送方的地址
if (0 < recvNum || 0 == recvNum) {
cout << "recv error" << GetLastError() << endl;
break;
}
cout << "server say:" << recvBuf << endl;
}
//关闭套接字
closesocket(sock);
//卸载库
WSACleanup();
}
运行结果
先运行客户端,后运行服务端。
启动

发送消息
尝试发送出错
- 错误查找

- 尝试解决1.更换端口号->不能解决2.优快云搜索


- 错误总结:客户端socket部分出现问题
- 检查代码
填写地址时有空格导致发送失败
纠错
- 运行结果


- 1.server没有输入要发送的数据
- 2.client客户端判断接收是否错误的条件错误。
- 修改

- 修改
- 运行结果

完整代码
#include<iostream>
#include<Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
int main() {
//加载库
WORD version = MAKEWORD(2, 2);
WSADATA data;
int err = WSAStartup(version,&data);
if (0 != err) {
cout << "WSAStartup error" << endl;
return 1;
}
if (HIBYTE(data.wVersion) != 2 || LOBYTE(data.wVersion) != 2) {
cout << "verion wrong!" << endl;
WSACleanup();
return 1;
}
else {
cout << "WSAStartup success"<<endl;
}
//创建套接字
SOCKET sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (INVALID_SOCKET == sock) {
cout << "socket error" << WSAGetLastError()<<endl;
WSACleanup();
return 1;
}
else {
cout << "socket success" << endl;
}
//填写地址
char sendBUf[9999] = "";
char recvBuf[9999] = "";
int sendLen = sizeof(sendBUf);
int recvLen = sizeof(recvBuf);
sockaddr_in addrTo;
int addrToLen = sizeof(addrTo);
addrTo.sin_addr.S_un.S_addr = inet_addr("192.168.0.111");
addrTo.sin_family = AF_INET;
addrTo.sin_port = htons(56789);
while (true) {
//发送数据
gets_s(sendBUf);
int senNum = sendto(sock,sendBUf,sendLen,0,(sockaddr*) & addrTo,sizeof(addrTo));
if (SOCKET_ERROR == senNum) {
cout << "send error" << GetLastError() << endl;
break;
}
//接收数据
//int recvNum = recvfrom(sock,recvBuf,recvLen,0,(sockaddr*)&addrTo,&addrToLen);
int recvNum = recvfrom(sock, recvBuf, recvLen, 0,nullptr,nullptr);
if (recvNum<0) {
cout << "recv error" << GetLastError() << endl;
break;
}
cout << "server say:" << recvBuf << endl;
}
//关闭套接字
closesocket(sock);
//卸载库
WSACleanup();
}
运行结果

351






