1.需要注意的是: ::bind(serSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) ,bind()函数前必须添加::,否则,在使用thread头文件后, 使用了using namespace std的情况下,会被默认成std::bind,导致编译失败
(1)server
#include<WinSock2.h>
#include<iostream>
#include <thread>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
//初始化socket资源
int gFlag = -1;
void threadFunc()
{
WSADATA WSAData;
WORD sockVersion = MAKEWORD(2, 2);
if (WSAStartup(sockVersion, &WSAData) != 0)
return ;
SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //创建服务器socket
if (INVALID_SOCKET == serSocket)
{
cout << "socket error!";
return ;
}
//设置传输协议、端口以及目的地址
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
if (::bind(serSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) //将socket绑定地址
{
cout << "bind error";
closesocket(serSocket);
return ;
}
sockaddr_in clientAddr;
int iAddrlen = sizeof(clientAddr);
char buff[1024]; //建立接收缓存字节数组
while(true)
{
memset(buff, 0, 1024); //清空接收缓存数组
//开始接收数据
int len = recvfrom(serSocket, buff, 1024, 0, (sockaddr*)&clientAddr, &iAddrlen);
if (len > 0)
{
cout << "客户端地址:" << inet_ntoa(clientAddr.sin_addr) << endl;
cout << buff;
std::string str_buff = buff;
//if(str_buff.compare("来自客户端的数据包。\n") == 0)
if (buff == "来自客户端的数据包。\n")
{
std::cout << "OK" << std::endl;
}
gFlag = 1;
// sendto(serSocket,buff,1024,0,(sockaddr*)&clientAddr,iAddrlen);
}
}
closesocket(serSocket); //关闭socket
WSACleanup();
}
void threadFunc2()
{
WSADATA WSAData;
WORD sockVersion = MAKEWORD(2, 2);
if (WSAStartup(sockVersion, &WSAData) != 0)
return;
SOCKET serSocket2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //创建服务器socket
if (INVALID_SOCKET == serSocket2)
{
cout << "socket2 error!";
return ;
}
//设置传输协议、端口以及目的地址
sockaddr_in serAddr2;
serAddr2.sin_family = AF_INET;
serAddr2.sin_port = htons(3333);
serAddr2.sin_addr.S_un.S_addr = INADDR_ANY;
if (::bind(serSocket2, (sockaddr*)&serAddr2, sizeof(serAddr2)) == SOCKET_ERROR) //将socket绑定地址
{
cout << "bind error";
closesocket(serSocket2);
return ;
}
sockaddr_in clientAddr2;
int iAddrlen2 = sizeof(clientAddr2);
char buff2[1024]; //建立接收缓存字节数组
while (true)
{
memset(buff2, 0, 1024); //清空接收缓存数组
//开始接收数据
int len2 = recvfrom(serSocket2, buff2, 1024, 0, (sockaddr*)&clientAddr2, &iAddrlen2);
if (len2 > 0)
{
cout << "客户端地址2:" << inet_ntoa(clientAddr2.sin_addr) << endl;
cout << buff2;
if (gFlag == 2)
{
gFlag = 3;
}
// sendto(serSocket,buff,1024,0,(sockaddr*)&clientAddr,iAddrlen);
}
}
closesocket(serSocket2); //关闭socket
WSACleanup();
}
void threadFun3()
{
while(true)
{
if(gFlag == 1)
{
gFlag = 2;
}
printf("gFlag :%d\n",gFlag);
Sleep(1000);
}
}
int main()
{
std::thread thread1(threadFunc);
std::thread thread2(threadFunc2);
std::thread thread3(threadFun3);
thread1.join();
thread2.join();
thread3.join();
return 0;
}
(2)client
#include<WinSock2.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
int main()
{
WSADATA WSAData;
WORD sockVersion = MAKEWORD(2, 2);
if (WSAStartup(sockVersion, &WSAData) != 0)
return 0;
SOCKET clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (INVALID_SOCKET == clientSocket)
{
cout << "socket error!";
return 0;
}
sockaddr_in dstAddr;
dstAddr.sin_family = AF_INET;
dstAddr.sin_port = htons(8888);
dstAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
const char* sendData = "heartbeat";
while(1)
{
sendto(clientSocket, sendData, strlen(sendData), 0, (sockaddr*)&dstAddr, sizeof(dstAddr));
Sleep(500);
}
closesocket(clientSocket);
WSACleanup();
return 0;
}
|