📄 receiver.c
字号:
// 模块名: Receiver.c
//
// 描述:
// 本例通过将套接字绑定到指定的网卡地址和端口号,然后调
// 用recvfrom()阻塞函数,来接收UDP数据报
//
// 编译方法:
// cl -o Receiver Receiver.c ws2_32.lib
//
// 命令行选项:
// sender [-p:int] [-i:IP][-n:x] [-b:x]
// -p:int 本地端口
// -i:IP 监听的本地IP地址
// -n:x 发送消息的次数
// -b:x 发送缓存区的大小
//
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define DEFAULT_PORT 5150
#define DEFAULT_COUNT 25
#define DEFAULT_BUFFER_LENGTH 4096
int iPort = DEFAULT_PORT; // 接收的端口
DWORD dwCount = DEFAULT_COUNT, // 读取消息的数目
dwLength = DEFAULT_BUFFER_LENGTH; // Length of receiving buffer
BOOL bInterface = FALSE; // 使用非默认的网卡
char szInterface[32]; // 读取数据报的网卡
//
// 函数: usage:
//
// 描述:
// 打印使用方法并退出程序t
//
void usage()
{
printf("usage: sender [-p:int] [-i:IP][-n:x] [-b:x]\n\n");
printf(" -p:int 本地端口\n");
printf(" -i:IP 监听的本地IP地址\n");
printf(" -n:x 发送消息的数目\n");
printf(" -b:x 发送缓冲区的大小\n\n");
ExitProcess(1);
}
//
// 函数: ValidateArgs
//
// 描述:
// 解析命令行参数,设置一些全局的标志,以便指示要完成的动作
//
void ValidateArgs(int argc, char **argv)
{
int i;
for(i = 1; i < argc; i++)
{
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
switch (tolower(argv[i][1]))
{
case 'p': // 本地端口
if (strlen(argv[i]) > 3)iPort = atoi(&argv[i][3]);
break;
case 'n': // 接收消息的次数
if (strlen(argv[i]) > 3)
dwCount = atol(&argv[i][3]);
break;
case 'b': // 缓冲区的尺寸
if (strlen(argv[i]) > 3)dwLength = atol(&argv[i][3]);
break;
case 'i': // 接收数据报的网络接口(网卡)
if (strlen(argv[i]) > 3)
{
bInterface = TRUE;
strcpy(szInterface, &argv[i][3]);
}
break;
default:
usage();
break;
}
}
}
}
//
// 主函数: main
//
// 描述:
// 执行主线程,初始化Winsock,解析命令行参数,创建套接字,将套接字
// 与本地网卡和端口绑定,然后读取数据报
//
int main(int argc, char **argv)
{
WSADATA wsd;
SOCKET s;
char *recvbuf = NULL;
int ret,
i;
DWORD dwSenderSize;
SOCKADDR_IN sender,
local;
// 解析命令行参数,装载Winsock
//
ValidateArgs(argc, argv);
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("装载Winsock失败!\n");
return 1;
}
// 创建套接字,并将它与本地网卡的IP地址和端口棒定
//
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("创建socket失败; %d\n", WSAGetLastError());
return 1;
}
local.sin_family = AF_INET;
local.sin_port = htons((short)iPort);
if (bInterface)
local.sin_addr.s_addr = inet_addr(szInterface);
else
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
{
printf("帮定socket失败: %d\n", WSAGetLastError());
return 1;
}
// 分配接收缓冲区
//
recvbuf = GlobalAlloc(GMEM_FIXED, dwLength);
if (!recvbuf)
{
printf("分配接收缓冲区失败: %d\n", GetLastError());
return 1;
}
// 读取数据报
//
for(i = 0; i < dwCount; i++)
{
dwSenderSize = sizeof(sender);
ret = recvfrom(s, recvbuf, dwLength, 0,(SOCKADDR *)&sender, &dwSenderSize);
if (ret == SOCKET_ERROR)
{
printf("接收数据报失败; %d\n", WSAGetLastError());
break;
}
else if (ret == 0)
break;
else
{
recvbuf[ret] = '\0';
printf("[%s] 被发送: '%s'\n",inet_ntoa(sender.sin_addr), recvbuf);
}
}
closesocket(s);
GlobalFree(recvbuf);
WSACleanup();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -