博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UDP客户端发送结构体数据,调用recvfrom函数阻塞问题
阅读量:4165 次
发布时间:2019-05-26

本文共 3110 字,大约阅读时间需要 10 分钟。

1.当我们想发送一个结构体给服务端时,如果该结构体是字节对齐,那么无需考虑大小端的转换

比如:

typedef struct OpenMessage

{
    int32_t  SessionType;
    int32_t  SessionId;
    int64_t  TimeStamp;

};

OpenMessage  kmessage;给结构体赋值后,char * sendbuffer = (char *)&kmessage;

2、UDP客户端/服务器端

当我们UDP定时(2s)给服务端发送数据,服务端收到数据后将此数据再发送给客户端,客户端接收,因此客户端和服务器端都会使用sendto和recvfrom,但是客户端程序当我们在一个主线程中使用sendto和recvfrom时,会出现recvfrom被阻塞,客户端没有周到数据也无法再发送数据。

UDPServer.cpp

#include 
#include
#include
#include
#include
#include
#include
#include
int UDPServer(){ int sock; struct sockaddr_in toAddr; struct sockaddr_in fromAddr; sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(sock < 0) { perror("socket!"); return -1; } memset(&fromAddr,0,sizeof(fromAddr)); fromAddr.sin_family=AF_INET; fromAddr.sin_addr.s_addr=inet_addr("0.0.0.0"); fromAddr.sin_port = htons(7861); if(bind(sock,(struct sockaddr*)&fromAddr,sizeof(fromAddr))<0) { perror("bind!"); close(sock); return -1; } int count =0; int recvLen; unsigned int addrLen; char recvBuffer[1024]={0}; while(1) { count ++; addrLen = sizeof(toAddr); //client recvLen = recvfrom(sock,recvBuffer,1024,0,(struct sockaddr*)&toAddr,&addrLen); if(recvLen>0) { recvBuffer[recvLen]= 0; printf("recv size:%2d,count = %2d\n",recvLen,count); int ret =0; ret = sendto(sock,recvBuffer,recvLen,0,(struct sockaddr*)&toAddr,sizeof(toAddr)); if(ret!=recvLen) { perror("sendto"); } } else { sleep(1); } } close(sock); return 0;}int main(int argc, char *argv[]){ UDPServer(); return 0;}

UDPClient.cpp

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct message{ int32_t SessionType; int32_t SessionId; int64_t TimeStamp;};int main(){ int socket_fd = socket(AF_INET, SOCK_DGRAM, 0); if(socket_fd == -1) { perror("udp_socket"); return -1; } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("192.168.154.201"); addr.sin_port = htons(4000); if (addr.sin_addr.s_addr == INADDR_NONE) { printf("Incorrect ip address!"); close(socket_fd); return -1; } char buff[1024]; int sessionId =0; socklen_t len = sizeof(addr); message sendmessages; while (1) { sleep(2); sessionId ++ ; sendmessages.SessionType = 1; sendmessages.SessionId = sessionId; sendmessages.TimeStamp = 9999; printf("client send:%d ,%d ,%lld \n", sendmessages.SessionType, sendmessages.SessionId, sendmessages.TimeStamp); char * sendbuffer = (char *)&sendmessages; int n; n = sendto(socket_fd, sendbuffer, sizeof(sendmessages), 0, (struct sockaddr *)&addr, sizeof(addr)); if (n < 0) { perror("sendto !"); } memset(buff,0,sizeof (buff)); n = recvfrom(socket_fd, buff, 1024, 0, (struct sockaddr *)&addr, &len); if (n>0) { message recv; memcpy(&recv, buff, sizeof(message)+1); buff[n] = 0; printf("client recv:%d ,%d ,%lld \n", recv.SessionType, recv.SessionId, recv.TimeStamp); } else { printf("recvfrom error!\n"); } close(socket_fd); return 0;}

如果想长时间客户端和服务器端交互,那么客户端出现被阻塞情况,一直收不到数据,也没有动力再去发送数据!!!

因为网络的问题,经常丢包,也就是发了之后没有响应。这样的话,recvfrom会一直停在那里,死机了一样。

 

转载地址:http://fjqxi.baihongyu.com/

你可能感兴趣的文章
寻找第K大
查看>>
String.trim
查看>>
缓存行 伪共享
查看>>
400 : perceived to be a client error 错误
查看>>
Establishing SSL connection without server's identity verification is not recommended
查看>>
扫描包不存在:pojo类找不到
查看>>
c语言中计算数组长度的方法
查看>>
java 数组定义
查看>>
java中的&和&&的区别
查看>>
Java的位运算符
查看>>
BufferedReader与Scanner的区别
查看>>
java String于常量池中的介绍
查看>>
java Text 错误: 找不到或无法加载主类 Text
查看>>
XShell连接ubantu:给ubantu安装ssh
查看>>
c语言的null和0
查看>>
二进制详解:世界上有10种人,一种懂二进制,一种不懂。
查看>>
c语言一个字符变量存储多个字符
查看>>
java接口中方法的默认访问修饰符为public
查看>>
java多线程之并发synchronized
查看>>
java多线程之并发Lock
查看>>