I've done a UDP socket server in C. The server works properly only if the packets are send to 127.0.0.1. I'm trying to test it with packet sender, and I want to open a socket at the address 192.168.231.54. Anyway, if I write this address in the code, I receive an error ("Cannot assign requested address"), and this error appears for each single address different from 127.0.0.1. I want to open a socket to 192.168.231.54 and I want to send packets to this address with Packet Sender.
Here is the server code:
//*********SOCKET OPENING**************
int fd;
struct sockaddr_in serveraddr, cliaddr;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror( "socket failed" );
exit(EXIT_FAILURE);
}
memset( &serveraddr, 0, sizeof(serveraddr) );
memset(&cliaddr, 0, sizeof(cliaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(50037);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if ( bind(fd, (const struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "bind failed" );
exit(EXIT_FAILURE);
}
else{
perror("socket opened");
}
//Receiving data into hex_array array
char hex_array[lenght];
int len;
len = sizeof(cliaddr);
int n = recvfrom(fd, (uint8_t *)hex_array, lenght, NULL, ( struct sockaddr *) &cliaddr, &len);
//Printing of the received data on the socket
printf("START DEBUG:\n");
printf("%s\n", hex_array);
printf("END DEBUG.\n");
The address you bind the socket to has to actually be your computer's IP address. You can't just pick a random address.
Related
I try to send a file data size of around 100MB from the client to the server in UDP ipv6.
the server I think it works well but the client I cannot figure out why I cannot send the file.
When I try to "sendto" I got the message: perror("[-]Error in sending the file. in UDP CLIENT")"
here is my code:
void client() {
int sockfd;
char buffer[65536];
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(P);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
FILE *fp = fopen("data.txt","r");
char data[SIZE] = {0};
while (fgets(data, SIZE, fp) != NULL) {
if (sendto(sockfd, data, sizeof(data),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr)) == -1) {
perror("[-]Error in sending file. in UDP CLIENT");
exit(1);
}
bzero(data, SIZE);
}
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *) buffer, 65536,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
}
First try with socket prog. any help why I get this error? This my server side code, till the part of bind (exluding listen etc)
thnx in advance
int main(){
unsigned int s; //returned by socket()
int port; //port number
int n; //fore read() & write()
int newsockfd; //returned by accept()
struct sockaddr_in server , client;
socklen_t clntLen; // Length of client address data structure
s = socket(AF_UNIX, SOCK_STREAM,0);
if(s==-1){
perror("Socket was not created\n");
return 0;
}
printf("Socket successfully created! ID: %d\n",s);
//sockaddr_in structure
memset( &server, 0, sizeof(server) ); // Zero structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons( 8888 );
//Bind
if( bind(s,(struct sockaddr *)&server , sizeof(server)) < 0){
//print the error message
perror("Bind failed! Error");
return 1;
}
printf("Bind completed successfully\n");
}
Use AF_INET instead of AF_UNIX in the call to socket().
I need my server to broadcast a message (not that it matters but it contains its IP/port info). What I have currently is the working server broadcast, code below. I'm not sure about setting up the client because usually I would use the IP/port of the server which the client doesn't have until it receives the broadcast. The client never receives anything. Can someone tell me what is wrong.
Server:
struct sockaddr_in server, bcast;
int sockfd;
int blen = sizeof(bcast);
int svrlen = sizeof(server);
char buf[BUFLEN];
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
printf("Socket error.\n");
exit(1);
}
int broadcastPermission = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void *)&broadcastPermission,sizeof(broadcastPermission)) < 0){
printf("Error setting socket options.");
}
memset(&bcast, 0, sizeof(bcast));
bcast.sin_family = AF_INET;
bcast.sin_port = htons(PORT);
bcast.sin_addr.s_addr = htonl(INADDR_ANY);
string bcastIP = BCASTIP;
if(inet_aton("255.255.255.255", &bcast.sin_addr) == 0){
printf("Broadcast Address error.");
exit(1);
}
if (bind(sockfd, (struct sockaddr*)&server, sizeof(server)) == -1){
printf("Port error.\n");
exit(1);
}
fflush(stdout);
if(int bytes = sendto(sockfd, ipinfo, sizeof(ipinfo), 0, (struct sockaddr*)&bcast, blen) == -1){
printf("Broadcast send error.");
}
else{
printf("Sent"):
}
Client:
struct sockaddr_in server;
int sockfd;
int bytes;
int svrlen = sizeof(server);
char buf[BUFLEN]
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
printf("Socket error.\n");
exit(1);
}
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(BPORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
while(1){
printf("Waiting for broadcast...\n\n");
fflush(stdout);
memset(buf,0,BUFLEN);
bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&server, (socklen_t*)&svrlen);
printf("Received");
}
Your client is not calling bind() on the socket before trying to receive data.
http://cs.baylor.edu/~donahoo/practical/CSockets/code/BroadcastReceiver.c shows the following example which you may find helpful:
void DieWithError(char *errorMessage); /* External error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket */
struct sockaddr_in broadcastAddr; /* Broadcast Address */
unsigned short broadcastPort; /* Port */
char recvString[MAXRECVSTRING+1]; /* Buffer for received string */
int recvStringLen; /* Length of received string */
if (argc != 2) /* Test for correct number of arguments */
{
fprintf(stderr,"Usage: %s <Broadcast Port>\n", argv[0]);
exit(1);
}
broadcastPort = atoi(argv[1]); /* First arg: broadcast port */
/* Create a best-effort datagram socket using UDP */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct bind structure */
memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */
broadcastAddr.sin_family = AF_INET; /* Internet address family */
broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
broadcastAddr.sin_port = htons(broadcastPort); /* Broadcast port */
/* Bind to the broadcast port */
if (bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)) < 0)
DieWithError("bind() failed");
/* Receive a single datagram from the server */
if ((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0)
DieWithError("recvfrom() failed");
recvString[recvStringLen] = '\0';
printf("Received: %s\n", recvString); /* Print the received string */
close(sock);
exit(0);
}
I need my server to broadcast a message (not that it matters but it contains its IP/port info).
That sounds a lot like service discovery. You should really use the standard mDNS/Zeroconf protocol for that. You can use the Avahi library for that (or use the Avahi service on Linux or Zeroconf on MacOS X).
I have opened an UDP socket to listen to incoming packet. I could see in the wireshark log the packets reaching the NIC. But the same is not available when reading via Socket. The 'netsatat ' command shows the port number is listened for the any incoming UDP messages. The socket reader keeps on waiting . I have checked using Java and C, in Linux(ubuntu) environment. I can see the Identification value for received IPV4 packet is 0. Is this value can play any role for a socket to read the data ?
My C code for reading the socket
int sock, n, nr;
socklen_t fromlen;
struct sockaddr_in server;
struct sockaddr_in from;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
printf("Can not create socket in server\n");
memset(&server, 0, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(5555);
server.sin_addr.s_addr = INADDR_ANY;
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
fromlen = sizeof(struct sockaddr_in);
while(1) {
printf("Waiting to receive\n");
n = recvfrom(sock, &nr, sizeof(nr), 0, (struct sockaddr *) &from, &fromlen);
printf("I have received");
}
Please find the wireshark trace http://imgur.com/Au9BeS1
This is a problem:
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
fromlen = sizeof(struct sockaddr_in);
This will only set fromlen is the bind call fails. And since fromlen is not properly initialized, it will contain a seemingly random value that is not valid for recvfrom.
Based from the answers I got from this thread, I've created this:
//Server
sock_init(); //from SFL, see http://legacy.imatix.com/html/sfl/
timeout = 50000;
serv_sock_input[0] = TCP(1234);
serv_sock_input[1] = UDP(9876);
input_protocols[0] = "tcp";
input_protocols[1] = "udp";
while (1)
{
FD_ZERO(&sock_set);
for (x = 0; x<number_of_inputs; x++)
{
FD_SET(serv_sock_input[x], &sock_set);
}
select_timeout.tv_sec = timeout;
select_timeout.tv_usec = 0;
if (select(0, &sock_set, NULL, NULL, &select_timeout) == 0)
printf("No requests");
else
{
for (x = 0; x<number_of_inputs; x++)
{
if (FD_ISSET(serv_sock_input[x],&sock_set))
{
printf("\nRequest on port %d: \n", x);
if ((strcmp(input_protocols[x],"tcp")) == 0) //in this case, 0 returned == TRUE
{
accept_socket(serv_sock_input[x]);
printf("Input TCP Port %d\n",x);
close_socket(serv_sock_input[x]);
}
else
{
printf("Input UDP Port %d\n",x);
}
}
}
}
}
sock_term();
}
int TCP (unsigned short port)
{
int sock;
struct sockaddr_in servAddr;
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
exit(1);
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
exit(1);
if (listen(sock, 5) < 0)
exit(1);
return sock;
}
int UDP (unsigned short port)
{
int sock; /* socket to create */
struct sockaddr_in servAddr; /* Local address */
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
exit(1);
/* Construct local address structure */
memset(&servAddr, 0, sizeof(servAddr)); /* Zero out structure */
servAddr.sin_family = AF_INET; /* Internet address family */
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
servAddr.sin_port = htons(port); /* Local port */
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
exit(1);
return sock;
}
//Client
sock_init();
if ((client_sock_output = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
exit(1);
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
client_addr.sin_port = htons(1234);
if (connect(client_sock_output, (struct sockaddr *) &client_addr, sizeof(client_addr)) < 0)
exit(1);
closesocket(client_sock_output);
sock_term();
When the server starts, the server gets blocked at the if(select(...)) statement.
So when I run the Server, and then the client, the client connects to the server (sometimes it takes a couple times to run the client before they connect). Then the if(select...)) statement is no longer true and it proceeds to the else.
After that, the client closes the connection, and the program. However, and this is where my problem happens, the if(select(...)) statement is always false. I get this output:
Request on port 0:
Input TCP Port 0
Request on port 1:
Input UDP Port 1
This output repeats forever. How come it doesn't get stuck at the if(select(...))?
You have two problems: you don't understand how accept() works in TCP, and you need to read the incoming data in UDP.
select() tells you that a listening socket has connection to accept, or reading socket has data to read.
For select to stop telling you this, you need to actually read the data or accept the connection.
In your UDP branch, you need to call receiv to actually get the data. If you don't, select will keep telling you that you have data.
In your TCP branch, you call accept_socket. I don't know what is your implementation of it, but it's most probably wrong to close the socket you just called accept() on. accept() returns a new socket for you - the one you should be using for IO. If anything needs to be closed, it's that new socket.
Please check why you have this in server.
if (select(0, &sock_set, NULL, NULL, &select_timeout) == 0)
replace it with
if (select(maxDescPlus1, &sock_set, NULL, NULL, &select_timeout) == 0)
where maxDescPlus1 --> is number of descriptors to select plus 1 value.