我尝试创建一个函数来打开一个名为libf_build_udp_socket
的套接字(我将来会有多个套接字)。但是当谈到绑定时我得到了错误cannot assign requested address
,如果我绕过这个绑定,我发送一个cmd时出错了。
如果我不使用我的功能并直接集成我的主要代码,它就能很好地工作。
为了解释我在linux下有一台计算机必须发送cmd并从不同的设备接收日志,如信号接收器......
这是我的完整代码,所以也许你会更好地了解我的目标。
/* Standard Linux headers */
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#include <errno.h>
/* DEFINE */
#define IP_RX "192.168.0.10" //notre IP=192.168.0.5
#define BUFFLEN 1024 //Max length of buffer
#define PORT_RX 3000 //The port on which to send data
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port);
int main (void)
{
/*
** Definition of the local variables.
*/
//SOCKET
struct sockaddr_in addr_rx;
int serv_len_rx=sizeof(addr_rx);
int socket_fd_rx;
unsigned short int socketStatus; /* Socket return status */
//FD
fd_set readfds;
//BUFFER & CMD
char recepbuff[BUFFLEN];
char cmd[BUFFLEN], cmd_final[BUFFLEN];
//OTHER
int i, recv;
char choice;
int loop=1;
//TIMEOUT STRUCT
struct timeval tv;
tv.tv_sec=0; /*timeout de 0sec*/
tv.tv_usec=1000; //NE MARCHE PAS SI =0
/*
** Initialisation of the local variables.
*/
memset(recepbuff, '0' ,sizeof(recepbuff)); /*pareil que bzero*/
i=0;
/*
** Creating the socket
** call socket (it creates an endpoint for communication and
** returns the socket descriptor.
** To create an UDP socket here are the param
** The protocol family should be AF_INET
** The protocol type is SOCK_DGRAM
** The protocol should beset to default ie
** DEF_PROTOCOL wich is default so 0. );
*/
//OPENING AND SETTING SOCKET RX
socketStatus = libf_build_udp_socket(&socket_fd_rx, IP_RX, PORT_RX);
if (socketStatus>0)
{
printf("Could not create the socket, code error %d\n", socketStatus);
return 0;
}
/* Messaging*/
while(1)
{
printf ("\n//Boucle %d\n", i);
//clear the buffer by filling null, it might have previously received data
memset(recepbuff, '\0' ,sizeof(recepbuff));
loop=1;
//preparing cmd
printf("Enter command :");
fgets(cmd, sizeof(cmd) , stdin);
snprintf(cmd_final, sizeof (cmd_final), cmd, "\r\n"); /*adding 0d 0a to the cmd*/
//send cmd
if ( (sendto(socket_fd_rx , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&addr_rx, serv_len_rx) ) < 0 )
{
perror("ERROR > send cmd failed to wass : ");
return 0;
}
else
{
printf( "cmd send to %s:%d\n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
}
//printf("\n... waiting answer from %s:%d ... \n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
//strcpy(recepbuff, "whileloop");
//try to receive some data, this is a blocking call
while(loop)
{
memset(recepbuff, '\0' ,sizeof(recepbuff)); //empty buffer
FD_ZERO(&readfds);
FD_SET(socket_fd_rx, &readfds); //set testing for rx
select(socket_fd_rx+1, &readfds, NULL, NULL, &tv); //block until cmd becomes available
if(FD_ISSET(socket_fd_rx, &readfds)) //input rx available
{
//printf("Data to be read \n");
recvfrom( socket_fd_rx, recepbuff , BUFFLEN, 0, (struct sockaddr *)&addr_rx, &serv_len_rx); //recep
printf("[=> Réponse : %s\n", recepbuff);
}
else
{
loop=0;
}
}
printf(".... Réponse done from %s:%d .... \n",inet_ntoa(addr_rx.sin_addr),ntohs(addr_rx.sin_port) );
i++;
}
close(socket_fd_rx);
return 0;
}
//FONCTIONS
//OPENING 1 SETTING A SOCKET
/** libf_build_udp_socket
*
* This function creates an UDP socket.
*
* \param udp_socket socket identifier
* \param server_address IP destination address
* \param udp_port Destination UDP port
* \param server_flag TRUE to bind socket on UDP port
*
* \return 0 if successful; error code otherwise
*/
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port)
{
/*
** Defining of the local variables.
*/
struct sockaddr_in serv_addr; /* Server Socket address structure*/
short int status = 0; /* internal status return*/
unsigned short int return_status = 0; /* the returnes status value */
/*
** creating the socket ;
** call socket (it creates an endpoint for communication and
** returns the socket
** descriptor. To create an UDP socket
** the parameter family is set
** to AF_INET, the type to SOCK_DGRAM, and
** the protocol to
** DEF_PROTOCOL. The socket is a global variable.);
*/
*udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (*udp_socket < 0)
{
return_status = 1;
}
else
{
status = 1; //for future check
if (status >= 0)
{
/*
** reset the serv_addr variable
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/*
** set the sockname.sin_addr.s_addr to server address;
** sockname.sin_addr.s_addr = htonl(server address);
** set the sockname field sockname.sin_port to the used port number;
** sockname.sin_port = htons (udp port);
*/
serv_addr.sin_addr.s_addr = inet_addr(server_address);
serv_addr.sin_port = htons(udp_port);
/*
** Bind this socket to a name;
** call bind (it assigns a name or address to an unnamed socket.
** When a socket is created with socket it exists in
** a name space (address family) but has no name assigned.
** The bind requests the name, be assigned to the socket);
** If (return status signal an error)
** {
** set to return variable to error
** }
*/
status = bind(*udp_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (status < 0)
{
printf("bind failed with %s", strerror(errno));
return_status = 2;
}
}
else
{
return_status = 3;
}
}
/*
** return status;
*/
return return_status;
}
也许我缺少套接字编程中必不可少的东西,我做了很多研究并尝试了不同的东西,但它仍然不想工作!我将不胜感激!谢谢!