【发布时间】:2019-08-06 22:52:12
【问题描述】:
所以,下面是我从公司继承的代码(由我不知道是谁编写的),该代码目前适用于我的特定场景: 设备(信号发生器)向我发送 UDP 数据,我需要接收、分析它们,有时还需要向设备发送命令(基于分析)。这是它的样子:
/*********************************************
** Communication Struct.
**********************************************/
typedef struct CtxCom
{
int socket_client; //socket
char* cmd; //command
char* recepbuff; //recepbuff
struct sockaddr_in addr_client; //contains IP and PORT
}CtxCom;
extern struct CtxCom init_Ctx_com ( char* IP_client, const int PORT_client, struct timeval timeout )
{
CtxCom ClientCom; //define struct
ClientCom.socket_client = socket(AF_INET, SOCK_DGRAM, 0); //Create the socket
if(ClientCom.socket_client < 0) //Check the creation of the socket
{
perror("[Init_Com] socket()");
exit(errno);
}
struct sockaddr_in addr_me = { 0 }; //create the server struct
addr_me.sin_addr.s_addr = htonl(INADDR_ANY); //any incoming IP
addr_me.sin_port = htons(PORT_client);
addr_me.sin_family = AF_INET; //address family
if(bind(ClientCom.socket_client,(struct sockaddr *) &addr_me, sizeof(addr_me)) < 0) //bind the socket
{
perror("[Init_Com] bind()");
exit(errno);
}
//conf equipment side
ClientCom.addr_client.sin_addr.s_addr = inet_addr(IP_client);
ClientCom.addr_client.sin_port = htons(PORT_client);
ClientCom.addr_client.sin_family = AF_INET;
//timeout
//setsockopt(ClientCom.socket_client , SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout , sizeof (struct timeval));
//fcntl(ClientCom.socket_client, F_SETFL, O_NONBLOCK); //set socket to non block
//Printf info
printf("[Init CtxCom]");
printf(" Socket connected and Client[%s:%d] configured *************** \n",
inet_ntoa(ClientCom.addr_client.sin_addr),
ntohs(ClientCom.addr_client.sin_port) );
return ClientCom;
}
/*Write char* cmd of size cmdSize in the socket specified*/
extern void write_client(struct CtxCom CtxCom, char* cmd, int cmdSize)
{
//adding 0x0a 0x0d to the end of a CMD
cmdSize+=2;
cmd[cmdSize-2]='\r';
cmd[cmdSize-1]='\n';
//send CMD
if(sendto(CtxCom.socket_client, cmd, cmdSize, 0, (struct sockaddr *)&(CtxCom.addr_client), sizeof(CtxCom.addr_client)) < 0)
{
perror("[Write_client] send()");
exit(errno);
}
else
{
//printf( "\n***************SEND OK [%s:%d]******************\n"
// ,inet_ntoa(CtxCom.addr_client.sin_addr), ntohs(CtxCom.addr_client.sin_port) );
}
}
* Give in output the char* strings outStringLLRX with a size of sizeOutStringLLRX*/
extern void read_client(
/*input*/ struct CtxCom CtxCom, struct timeval timeout,
/*output*/ char** outStringLLRX, int* sizeOutStringLLRX)
{
//timeout forced
//timeout.tv_usec=TIMEOUT_LISTEN_GIII;
//Define variables
fd_set readfs;
int loop=1;
int i=0, k=0, z=0, z_prev=0;
int res;
char buf[25500];
int sizeBuf;
//Init variables
memset(buf, '\0' ,sizeof(buf));
for(i=0;i<NB_CHANNELS_LLRX;i++)
{
sizeOutStringLLRX[i]=0;
outStringLLRX[i][0]='\0';
}
//Make sure buffer is empty
memset(buf, '\0' ,sizeof(buf)); //empty recep buffer
FD_ZERO(&readfs); //zero testing
FD_SET(CtxCom.socket_client, &readfs); // set testing
//block until input becomes available
res=select(CtxCom.socket_client+1, &readfs, NULL, NULL, &timeout);
switch (res)
{
case 0: //timeout
printf("TIMEOUT error [Read Client] - No data received \n");
break;
case -1: //error
printf("Error [Read Client] \n");
break;
default : //streams event
if( FD_ISSET(CtxCom.socket_client, &readfs) )
{
sizeBuf=recvfrom (CtxCom.socket_client, buf , 25500, 0, NULL, NULL); //already now wich IP, no need to update
if ( sizeBuf<0 ) //if <0 => no data => error
{
printf("[Read_Client] Read failed : SizeBuf<0 \n");
}
else
{
printf("[Read_Client] Got a buffer of size %d (round %d) \n", sizeBuf, k);
(sizeOutStringLLRX[0])+=sizeBuf;
for( z=0; z<sizeBuf; z++) {outStringLLRX[0][z_prev]=buf[z]; z_prev++;}
}
}
break;
}//switch
//printf("[Read_Client] final size =%d\n", z_prev);
/*printf("***************RECV OK [%s:%d]******************\n",
inet_ntoa(CtxCom.addr_client.sin_addr),ntohs(CtxCom.addr_client.sin_port) );*/
}
我已经阅读了 socket 课程和 bind() man,但我仍然想知道:如果我有另一个设备在同一子网上发送数据,但在广播中(在 x.255 上)。这会污染插座吗?有时当我从我的设备接收数据时在同一个套接字上我收到了广播而不是(或另外)? 就我而言,bind 实际上只是为了给套接字“命名”,而不是像评论中写的那样接受任何传入的 IP 地址?
(顺便说一句,如果这里写的东西真的很糟糕,请告诉我,我很乐意让这段代码变得更好)
【问题讨论】: