本文共 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/