windows udp demo
server:
// win_tcp_server.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Ws2tcpip.h>
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
int main(int argc,char *argv[])
{
// 加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
// Winsock库版本,低字节代表主版本,高字节代表副版本
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return -1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
//终止对winsock库的使用
WSACleanup();
return -1;
}
// 创建套接字
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
//************绑定到本机地址和端口***********
SOCKADDR_IN addrSrv;//本机地址结构体信息,除了sin_family,其它字段都需要采用网络字节序
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//htonl转换为网络字节序,转换的是u_long类型
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);//htons转换为网络字节序,转换的是u_short类型
// recvfrom 出现10054的错误
DWORD dwByteReturned = 0;
BOOL bNewBehavior = FALSE;
DWORD status;
status = WSAIoctl(sockSrv, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior), NULL, 0, &dwByteReturned, NULL, NULL);
// 绑定
int ret = bind(sockSrv, (SOCKADDR*)& addrSrv, sizeof(addrSrv));
if (!ret) {
printf("bind success\n");
}
else {
printf("bind ret %d\n",ret);
return ret;
}
ret = 1;
while (ret > 0)
{
char sendbuf[1500] = { 0 };
SOCKADDR_IN fromaddr;
char fromaddrstr[40];
int fromaddrlen = sizeof(SOCKADDR_IN);
ret = recvfrom(sockSrv, sendbuf, sizeof(sendbuf), 0, (SOCKADDR*)&fromaddr, &fromaddrlen);
if (ret <= 0)
{
int er = GetLastError();
printf("ret %d,error 0x%x,%d\n", ret, er, er);
}
else
{
inet_ntop(AF_INET, &fromaddr.sin_addr, fromaddrstr, sizeof(fromaddrstr));
printf("ret %d,recv from %s:%d %s\n", ret, fromaddrstr, ntohs(fromaddr.sin_port), sendbuf);
strcat(sendbuf, " res from server");
sendto(sockSrv, sendbuf, (int)strlen(sendbuf), 0, (struct sockaddr*) & fromaddr, sizeof(struct sockaddr));
}
}
//关闭套接字
closesocket(sockSrv);
//终止套接字库的使用
WSACleanup();
return 0;
}
client:
// win_tcp_client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
#include <stdlib.h>
#include <Ws2tcpip.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#pragma comment( lib, "ws2_32.lib" )
#pragma warning(disable:4996)
int main(int argc, char* argv[])
{
// 加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
// Winsock库版本,低字节代表主版本,高字节代表副版本
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
return -1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
//终止对winsock库的使用
WSACleanup();
return -1;
}
const char* ipstr = "127.0.0.1";
SOCKET clientSock;
SOCKADDR_IN ServerAddr = { 0 };
clientSock = socket(AF_INET, SOCK_DGRAM, 0);
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(6000);
ServerAddr.sin_addr.s_addr = inet_addr(ipstr);
int ret = 1;
int i = 0;
while (ret)
{
char buf[1500] = { 0 };
sprintf(buf,"<%d> msg to server",i++);
ret = sendto(clientSock, buf, (int)strlen(buf), 0, (struct sockaddr*) & ServerAddr, sizeof(struct sockaddr));
if (ret <= 0) {
printf("sendto err,ret %d,error %d",ret,GetLastError());
}
SOCKADDR_IN fromaddr;
char fromaddrstr[40];
int fromaddrlen = sizeof(SOCKADDR_IN);
memset(buf, 0, sizeof(buf));
ret = recvfrom(clientSock, buf, sizeof(buf), 0, (SOCKADDR*)& fromaddr, &fromaddrlen);
if (ret > 0)
{
inet_ntop(AF_INET, &fromaddr.sin_addr, fromaddrstr, sizeof(fromaddrstr));
printf("recv from %s len %d,%s\n", fromaddrstr,ret,buf);
}
Sleep(3000);
}
closesocket(clientSock);
WSACleanup();
}
运行结果: