UDP广播测试端口复用 SO_REUSEADDR

 

#define LOG_TAG "ut_SocketReusePort"

#include <gtest/gtest.h>
#include <utils/RefBase.h>
#include <utils/Thread.h>
#include <osal/network_util.h>
#include <utils/List.h>
#include <utils/StrongPointer.h>
#include <utils/Buffer.h>
#include <utils/Handler.h>
using namespace twl;

int srp_startSink();
int srp_startSrc();

class server:public Handler
{
public:
	server(){};
	  ~server(){};
protected:
	void onMessageReceived(const sp<Message> &msg){
		srp_startSink();
	}
};

class client:public Handler
{
public:
	client(){};
	~client(){};
protected:
	void onMessageReceived(const sp<Message> &msg){
		srp_startSrc();
	}
};

//
void srp_start_test(){
	net_Init();
	sp<server> servServer1 = new server();
	sp<server> servServer2 = new server();

	sp<client> servClient = new client();

	sp<Looper> looperServer1 = new Looper();
	sp<Looper> looperServer2 = new Looper();

	sp<Looper> looperClient1 = new Looper();

	looperServer1->registerHandler(servServer1);
	looperServer2->registerHandler(servServer2);
	Sleep(2000);//wait for server start up.
	looperClient1->registerHandler(servClient);

	looperServer1->start();
	looperServer2->start();
	looperClient1->start();

	sp<Message> msg1 = new Message();
	msg1->setTarget(servServer1->id());
	msg1->post();
	msg1->setTarget(servServer2->id());
	msg1->post();


	sp<Message> msg2 = new Message(0,servClient->id());
	msg2->post();

	while(getchar());
}

#define  SOKCET_SINK_PORT			(76364)
#define  SOCKET_BUFFER_SIZE		(1024 * 100)
//
int srp_startSink(){
	int res;
	sockaddr_in in;
	memset(&in,0x00,sizeof(in));
	in.sin_family=AF_INET;
	in.sin_port=htons(SOKCET_SINK_PORT);
	in.sin_addr.s_addr=INADDR_ANY;

	int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	if(fd <= -1){
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_BROADCAST, 1);
	if (res < 0) {
		return net_errno;
	}

	printf("创建socket(%d)\n",fd);

	if(net_SetNonBlock(fd,0) <= -1)
		return -1;
	int nOptval;
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_REUSEADDR, 1);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_RCVBUF, SOCKET_BUFFER_SIZE);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}

	res = net_setSockoptInt(fd, SOL_SOCKET, SO_SNDBUF, SOCKET_BUFFER_SIZE);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}
		
	// 绑定这个套节字到一个本地地址
	if(::bind(fd, (LPSOCKADDR)&in, sizeof(in)) == SOCKET_ERROR)
	{
		printf("Failed bind() \n");
		return 0;
	}

	printf("等待接收数据socket(%d)\n",fd);

	long lRecOnce = 0;
	sockaddr_in addr;
	int addrlen = sizeof(addr);
	CHAR szRecvBuf[SOCKET_BUFFER_SIZE];	
	while (1)
	{
		lRecOnce = ::recvfrom(fd, szRecvBuf, SOCKET_BUFFER_SIZE, 0, (sockaddr*)&addr, &addrlen); 
		if (lRecOnce<=0)
			return -1;
		szRecvBuf[lRecOnce] = '\0';
		printf("接收到数据 socket:%d:%s", fd, szRecvBuf);
	}
	
	return -1;
}





//

int srp_startSrc(){
	int res;
	int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_BROADCAST, 1);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_REUSEADDR, 1);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}
	res = net_setSockoptInt( fd, SOL_SOCKET, SO_RCVBUF, SOCKET_BUFFER_SIZE);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}

	res = net_setSockoptInt(fd, SOL_SOCKET, SO_SNDBUF, SOCKET_BUFFER_SIZE);
	if (res < 0) {
		printf("socket error:%d\n",net_errno);
		return net_errno;
	}

	// 填写远程地址信息
	sockaddr_in addr; 
	addr.sin_family = AF_INET;
	addr.sin_port = htons(SOKCET_SINK_PORT);
	addr.sin_addr.S_un.S_addr = INADDR_BROADCAST;

	for (;;)
	{
		// 发送数据
		char szText[] = " socket packet test.\r\n";
		int sendOnce = ::sendto(fd, szText, strlen(szText), 0, (sockaddr*)&addr, sizeof(addr));
		if(sendOnce <= -1){
			printf("socket error:%d\n",net_errno);
			return net_errno;
		}
		printf("发送出数据(%s):%s", ::inet_ntoa(addr.sin_addr), szText);
		Sleep(2000);
	}

	::closesocket(fd);
	return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白錵錵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值