- 代码来源于 》》》》》》》》》》》》》》》》》》》》》 Windows Sockets网络开发VC++ 这本书
- 在stdafx.h 中添加 #pragma comment(lib,"ws2_32.lib")
服务端程序
// ServerUDP.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "winsock2.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf("serverUDP\n");
//**********************************************创建套接字
WSADATA wsd; //WSADATA变量
SOCKET s; //套接字
//初始化套接字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return -1;
}
//创建套接字
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("socket() failed; %d\n", WSAGetLastError());
WSACleanup(); //释放套接字资源
return -1;
}
//**********************************************绑定套接字
SOCKADDR_IN servAddr; //服务器地址
char optval = -1;
int optlen = -1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, optlen); //检测端口复用
//服务器套接字地址
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons((short)5000); //端口
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP
//绑定套接字
if(bind(s, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
printf("bind() failed: %d\n",WSAGetLastError());
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}
//**********************************************接收并显示数据
/* 用于接收数据,并返回发送数据主机地址
int recvfrom(
SOCKET s, //套接字
char FAR * nuf, //接收数据缓冲区
int len, //接收数据缓冲区大小
int flags, // 0表示无特殊行为,MSG_PEEK 会使有用的数据被复制到接收缓冲区内,但没有系统缓冲区中将其删除,MSG_OOB表示处理带外数据
struct sockaddr FAR * from, //该参数返回发送数据主机的地址
int FAR* fromlen //地址长度
)
return:成功:返回接收数据的字节数
失败:返回SOCKET_ERROR错误
*/
#define BUF_SZIE 64
char buf[BUF_SZIE]; //接收数据缓冲区s
//接收数据
SOCKADDR_IN clientAddr;
int nClientLen = sizeof(clientAddr);
ZeroMemory(buf, BUF_SZIE);
if (recvfrom(s, buf, BUF_SZIE, 0, (SOCKADDR*)&clientAddr, &nClientLen) == SOCKET_ERROR)
{
printf("recvfrom() failed:%d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return -1;
}
printf("%s\n", buf); //输出接收的数据
//**********************************************退出
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return 0;
}
客户端程序
// ClientUDP.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "winsock2.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf("ClientUDP\n");
//**********************************************创建套接字
WSADATA wsd; //WSADATA变量
SOCKET s; //套接字
//初始化套接字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return -1;
}
//创建套接字
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("socket() failed; %d\n", WSAGetLastError());
WSACleanup(); //释放套接字资源
return -1;
}
//**********************************************发送数据
/* 实现发送数据的功能
int sendto(
SOCKET s, //套接字
const char FAR * buf, //发送数据缓冲区
int len, //发送数据缓冲区大小
int flags, //0表示无特殊行为,MSG_DONTROUTE标志要求传输层不要将数据路由出去,MSG_OOB标志预示该数据应该被带外发送
const struct sockaddr FAR* to, //接收数据地址
int tolen //地址长度
)
return:成功:返回发送数据的字节数
失败:返回SOCKET_ERROR错误
*/
#define BUF_SZIE 64
char buf[BUF_SZIE]; //接收数据缓冲区
SOCKADDR_IN servAddr; //服务器地址
ZeroMemory(buf, BUF_SZIE);
strcpy_s(buf, "MyUDP");
//服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons((short)5000);
int nServAddlen = sizeof(servAddr);
//发送数据
if (sendto(s, buf, BUF_SZIE, 0, (SOCKADDR*)&servAddr, nServAddlen) == SOCKET_ERROR)
{
printf("recvfrom() failed: %d\n",WSAGetLastError());
closesocket(s);
WSACleanup();
return -1;
}
//**********************************************退出
closesocket(s); //关闭套接字
WSACleanup(); //释放套接字资源
return 0;
}
先打开server 后打开client
效果图