您的位置:首页 > 编程语言

UDP端口复用测试代码

2013-09-11 14:45 232 查看
具体不多说,看注释。

// udp.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
WORD ver = MAKEWORD(2,2);
WSAData data;
if (WSAStartup(ver,&data)!=0)
{
printf("WSAStartup() error:%d\n",WSAGetLastError());
return -1;
}
SOCKET s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
SOCKET s1 = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (s==INVALID_SOCKET)
{
printf("socket() error:%d",WSAGetLastError());
return -1;
}
if(s1==INVALID_SOCKET)
{
printf("socket() error:%d",WSAGetLastError());
return -1;
}
// 两个都都要设置端口复用
int flag = 1;
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt for s error:%d",WSAGetLastError());
}
if(setsockopt(s1,SOL_SOCKET,SO_REUSEADDR,(char*)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt for s1 error:%d",WSAGetLastError());
}
// 一些常规变量
char buff[256];
struct sockaddr_in sin;
int portbase = 15008;
int len = sizeof(sin);
int size;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(portbase);
// 第一次循环绑定,直到成功,入站地址使用INADDR_ANY
while (bind(s,(struct sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("bind() s port:%d error:%d\n",portbase,WSAGetLastError());
portbase++;
sin.sin_port = htons(portbase);
}
// 第二次绑定,需要用其他地址,入站地址用本地网卡的LAN地址
sin.sin_addr.s_addr = inet_addr("192.168.1.147");
if (bind(s1,(struct sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("bind() s1 port:%d error:%d\n",portbase,WSAGetLastError());
}
// 通过实验发现,直接绑定本地网卡LAN地址在接收上有优先级,端口复用后只有一个SOCKET能正常接收
while(true)
{
ZeroMemory(&sin,len);
size = recvfrom(s1,buff,256,0,(sockaddr*)&sin,&len);
if(size>0)
{
buff[size]=0;
printf("s1 msg: len=%d %s\n",size,buff);
}
sockaddr_in toAddr;
toAddr.sin_family = AF_INET;
toAddr.sin_port = htons(15009);
toAddr.sin_addr.s_addr = inet_addr("192.168.1.147");
// 两个SOCKET都能正常发送
sendto(s,"hello\r\n",7,0,(struct sockaddr*)&toAddr,sizeof(toAddr));
sendto(s1,"world\r\n",7,0,(struct sockaddr*)&toAddr,sizeof(toAddr));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: