/*
本程序是想测试一下,一个套接字阻塞在recvfrom的时候,能否sendto
有两个线程,一个线程负责阻塞接受,另一个线程延时2s之后,尝试sendto
*/
#include <WinSock2.h>
#include<stdio.h>
#include<pthread.h>
#include<time.h>
#pragma comment(lib,"pthread.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
int SaveFrame = 0;
bool StopWork = 0;
typedef struct mypara
{
SOCKET sock_host;
sockaddr_in *addr_remote;
}mypara;
void * Synchronization(void *arg);
int setUDPBroadcast(SOCKET sock_host);
void CreatThreadVal(pthread_t *pid, pthread_attr_t *attr);
void *Broadcast(void *arg);
int main()
{
WSADATA wsa;
WSAStartup(0x201, &wsa);
SOCKET sock_host; // 用于设备发现,
sock_host = socket(AF_INET, SOCK_DGRAM, 0);
// 设置广播参数,并与端口2019绑定
if (setUDPBroadcast(sock_host) == -1)
{
printf("UDP广播设置失败\n");
return -1;
}
sockaddr_in *addr_remote = new sockaddr_in;
addr_remote->sin_addr.S_un.S_addr = inet_addr("255.255.255.255");
addr_remote->sin_port = htons(2019);
addr_remote->sin_family = AF_INET;
mypara pstru ;
pstru.addr_remote = addr_remote;
pstru.sock_host = sock_host;
// 开启UDP服务器
pthread_t *ThreadPidUDPServer = new pthread_t;
pthread_attr_t *ThreadAttrUDPServer = new pthread_attr_t;
CreatThreadVal(ThreadPidUDPServer, ThreadAttrUDPServer);
pthread_attr_init(ThreadAttrUDPServer);
pthread_attr_setscope(ThreadAttrUDPServer, PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(ThreadAttrUDPServer, PTHREAD_CREATE_DETACHED);
pthread_create(ThreadPidUDPServer, ThreadAttrUDPServer, Synchronization, &pstru);
// 发送UDP广播报文
pthread_t *ThreadPidUDPBroadcast = new pthread_t;
pthread_attr_t *ThreadAttrUDPBroadcast = new pthread_attr_t;
CreatThreadVal(ThreadPidUDPBroadcast, ThreadAttrUDPBroadcast);
pthread_attr_init(ThreadAttrUDPBroadcast);
pthread_attr_setscope(ThreadAttrUDPBroadcast, PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(ThreadAttrUDPBroadcast, PTHREAD_CREATE_DETACHED);
pthread_create(ThreadPidUDPBroadcast, ThreadAttrUDPBroadcast, Broadcast, &pstru);
while (1);
//pthread_join(*ThreadPidUDPBroadcast, NULL);
return 0;
}
void CreatThreadVal(pthread_t *pid, pthread_attr_t *attr)
{
pid = (pthread_t *)malloc(sizeof(pthread_t));
attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
}
int setUDPBroadcast(SOCKET sock_host)
{
BOOL bBoardcast = TRUE;
if (SOCKET_ERROR == setsockopt(sock_host, SOL_SOCKET, SO_BROADCAST, (char*)&bBoardcast, sizeof(bBoardcast)))
{
printf("setsockopt设置udp广播失败 error code: %d\n", WSAGetLastError());
return -1;
}
else
{
sockaddr_in addr_local;
addr_local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr_local.sin_port = htons(2019);
addr_local.sin_family = AF_INET;
if (bind(sock_host, (sockaddr *)&addr_local, sizeof(addr_local)) != 0)
{
printf("bind设置udp广播失败 error code: %d\n", WSAGetLastError());
return -1;
}
}
return 0;
}
void * Synchronization(void *arg)
{
mypara *pstru;
pstru = (struct mypara *) arg;
SOCKET sock_host = pstru->sock_host;
sockaddr_in *addr_remote = pstru->addr_remote;
char buff[1024];
int retval;
while (true)
{
printf("UDP服务器开启...\n");
retval = recvfrom(sock_host, buff, 1024, 0, NULL, NULL);
printf("UDP服务器收到数据...\n");
if (retval <= 0)
{
retval = WSAGetLastError();
printf("服务端socket异常\n code:%d", retval);
return NULL;
}
printf(buff);
if (strcmp(buff, "start") == 0)
{
SaveFrame = 1;
}
if (strcmp(buff, "stop") == 0)
{
if (SaveFrame != 1)
SaveFrame = 0;
}
if (strcmp(buff, "exit") == 0)
{
StopWork = 1;
}
}
return 0;
}
void *Broadcast(void *arg)
{
printf("进入子线程");
mypara *pstru;
pstru = (struct mypara *) arg;
SOCKET sock_host = pstru->sock_host;
sockaddr_in *addr_remote = pstru->addr_remote;
int retval, headlen = sizeof(sockaddr_in);
char buff[1024] = "asdasdasd";
printf("开始睡眠1s\n");
Sleep(1000);
printf("开始发送UDP报文\n");
retval = sendto(sock_host, buff, strlen(buff), 0, (sockaddr *)addr_remote, headlen);
if (retval <= 0)
{
printf("发送失败 %d\n", WSAGetLastError());
return NULL;
}
printf("广播报文发送成功\n");
}
UDP套接字在一个特定端口上阻塞接收报文的时候,可以用这个套接字发送数据
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 内部缓冲区在系统内部,每个Socket关联了两个缓冲区(Buffer),一个用于接收(RecvBuf),一个用于发...
- 初次接触redux从而在网络上找学习资源。 react+redux系列教程 对react+redux教程(一) 文...