UDP C Server sendto() error: Can't assign requested address - c

I'm writing a basic Client/Server program in C, using UDP. The idea of the program is that the client sends a message to the server, the server receives it, then echoes it back to the client (the goal being to measure RTT for UDP). Unfortunately, on the server side, when the program attempts to call sendto() to echo the message, I receive the error "Can't assign requested address".
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#define SERVER_PORT 7000
#define MAX_PENDING 10
#define MAX_LINE 1024000
int main()
{
struct sockaddr_in sin, sout;
socklen_t soutLen;
char buf[MAX_LINE];
int len;
int msgLen;
int s;
char *msg;
if( (s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
perror("could not establish UDP socket");
exit(1);
}
/* build address data structure */
bzero((char *)& sin, sizeof( sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
if( (bind(s, (struct sockaddr *)&sin, sizeof(sin))) < 0){
perror("udpServer: bind");
exit( 1);
}
while(1){
if((msgLen = recvfrom(s, buf, sizeof(buf), 0,(struct sockaddr *)&sout, &soutLen))<0){
perror("udpServer: recvfrom()");
exit( 1);
}
if( (sendto(s, buf, msgLen, 0, (struct sockaddr *)&sout, sizeof(sout)))<0 ){
perror("udpServer: sendto()");
exit( 1);
}
free(msg);
}
}
Thanks in advance: I'm pretty new to C, so any advice is much appreciated!

The problem is that your sout you pass to sendto is not correct, because you are not correctly setting it's size when passing it to recvfrom:
man recvfrom:
ssize_t
recvfrom(int socket, void *restrict buffer, size_t length,
int flags, struct sockaddr *restrict address,
socklen_t *restrict address_len);
If address is not a null pointer and the socket is not connection-oriented, the source address of the message is filled in. The address_len argument is a
value-result argument, initialized to the size of the buffer associated with address, and modified on return to indicate the actual size of the address
stored there.
When you pass &sout to recvfrom, you also have to tell recvfrom the size of the structure you're passing in so it knows how much data it can write there -- soutLen is both an in parameter and an out parameter. Since you are not initializing soutLen, it probably has some value smaller than the actual size of the structure, which means that what you end up with in sout is not valid.
So you need to initialize soutLen:
struct sockaddr_in sin, sout;
socklen_t soutLen = sizeof(sout);
You should then pass this value as the size to sendto instead of sizeouf(sout) (this may not be required but it's good practice):
if( (sendto(s, buf, msgLen, 0, (struct sockaddr *)&sout, soutLen))<0 ){
Also just as a note, you are freeing msg which you never allocated. This is unrelated but might cause problems later.
Hope this helps.

Related

Program to establish connection then print out data it receives in C (sockets)

So I'm trying to get used to sockets, as I need to use them to create an intrusion detection program for upcoming coursework.
Something im trying to do at the moment is simply set up a socket file descriptor, bind it to an address, let it listen for any incoming requests, accept them then write them to a file.
The problems i'm having at the moment is, though what I think I'm doing here is correct, I kind of lost my way past the listen() call. I've tried to figure this out and look up the functions but something just isn't clicking at the moment. I've been at this for the past 6 hours and I've hit a dead end.
This code causes a segmentation fault, no doubt caused by the attempt at writing from the connection stream to the output stream.
Two main things I'd really appreciate:
A) Is my current understanding of whats happening (displayed by comments) correct?
B) If anyone could help me with the segmentation fault or suggest a better way to get the data receieved after establishing a connection out to a file that'd be great.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MYPORT 3490
#define BACKLOG 10
int main(void)
{
int sockfd = (AF_INET, SOCK_STREAM, 0);
//creates socket file descriptor
struct sockaddr_in servaddr;
// creates sockaddr_in structure
memset(&servaddr, 0, sizeof(servaddr));
//zeros out values in servaddr
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//sets contraints for servaddr
bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
//binds sockfd socket file descriptor to a sockaddr pointer pointing to
//memory location of our sockaddr_in servaddr
listen(sockfd, BACKLOG);
//listen for incoming connections
struct sockaddr their_addr;
socklen_t addr_size;
int new_fd;
//initialise sockaddr to store connector/clients socket address
//create socklen_t (dont know what this is) for the size of their socket
//new_fd for a new socket
addr_size = sizeof(their_addr);
new_fd = accept(sockfd, (struct sockaddr*) &their_addr, &addr_size );
//set the new socket equal to the result of our accept()
//accept takes the first connection queued on the host socket, pointer
//to a sockaddr where the connecting socket will be returned and
//the size of the structure to be allocated
FILE * conn_f = fdopen(new_fd, "w+");
FILE * output_f = fopen("receiver.txt", "w+");
//Here I try and set up two streams.
//One connection stream - conn_f which takes input from our new socket
//One output stream output_f - which writes to a text file
char *line = NULL;
size_t len = 0;
ssize_t bytes;
while ((bytes = getline(&line, &len, conn_f)) != -1) {
printf("Retrieved line of length %zu : %s\n", bytes, line);
fwrite(line, sizeof(char), bytes, output_f);
}
free(line);
//This was my attempt at reading the input line by line from my connection
//stream, (conn_f) and writing it to my output stream (output_f)
//I think this is causing the seg fault ^^
close(conn_f);
close(output_f);
return 0;
}

c- valgrind (Invalid free() / delete / delete[] / realloc()) Socketing

I am writing a simple program using sockets to receive actual date from server.
I am getting this error and i don't know where i am making a mistake.
Client:
/* Make the necessary includes and set up the variables. */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main ()
{
int sockfd;
socklen_t len;
struct sockaddr_in address;
int result;
int id=2, answer, length;
char *s;
/* Create a socket for the client. */
sockfd = socket (AF_INET, SOCK_STREAM, 0);
/* Name the socket, as agreed with the server. */
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr ("127.0.0.1");
address.sin_port = htons (9734);
len = sizeof (address);
/* Now connect our socket to the server's socket. */
result = connect (sockfd, (struct sockaddr *) &address, len);
if (result == -1)
{
perror ("oops: netclient");
exit (1);
}
/* We can now read/write via sockfd. */
write(sockfd, &id, sizeof(id)); /* sending the request id */
read(sockfd, &answer, sizeof(answer)); /* receiving the answer id*/
if(answer==1002){
printf("Odebrano wlasciwa odpowiedz\n");
read(sockfd, &length, sizeof(length)); /* receiving the answer string length*/
s=(char*)malloc(length*sizeof(char)); /* receiving the string with the date */
read(sockfd, s, length);
printf ("Date from server = %s\n", s);
}
free(s);
close (sockfd);
exit (0);
}
Server:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
int main ()
{
int server_sockfd, client_sockfd;
int length;
char *s;
int id;
int answer=1002;
socklen_t server_len, client_len;
time_t rtime;
struct tm *timeinfo;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
server_sockfd = socket (AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl (INADDR_ANY);
server_address.sin_port = htons (9734);
server_len = sizeof (server_address);
bind (server_sockfd, (struct sockaddr *) &server_address, server_len);
/* Create a connection queue and wait for clients. */
listen (server_sockfd, 5);
while (1)
{
printf ("server waiting\n");
/* Accept connection. */
client_len = sizeof (client_address);
client_sockfd = accept (server_sockfd,
(struct sockaddr *) &client_address,
&client_len);
/* We can now read/write to the client on client_sockfd.
The five second delay is just for this demonstration. */
read(client_sockfd, &id, sizeof(int)); /*receive request id */
if(id==2){
write(client_sockfd, &answer, sizeof(int)); /* sending an answer_id*/
time(&rtime);
timeinfo=localtime(&rtime);
s=(char*)malloc(sizeof(asctime(timeinfo))*sizeof(char));
printf("%s\n", asctime(timeinfo));
s=asctime(timeinfo);
printf("Size of s:%lx\n", sizeof(s));
length = htons(strlen(s));
write (client_sockfd, &length, sizeof(length)); /* sending the answer string length to the client */
printf("Date: %s\n", s);
write (client_sockfd, s, length); /* sending string with date to the server */
}
free(s);
close (client_sockfd);
}
}
I am almost certain that there is something wrong with allocing/freeing the space with the string containing actual date but i can't see the actual mistake.
EDIT:
Actually, i didn't know how to solve this problem in this mentioned way but i've came up with other idea.
I just send the result of asctime(timeinfo) over the server without using char* s.
So i don't write the date to char *s.
Program works fine now with no errors but i guess there is a way to do it some other way.
Well, even though, many thanks for the help, was helpful.
In your server, you overwrite s with asctime(...) after allocating it. This leaks the original memory. Also, the return value of asctime is a static buffer that cannot be freed.
Here's an excerpt from your code:
char *s;
if(answer==1002){
printf("Odebrano wlasciwa odpowiedz\n");
read(sockfd, &length, sizeof(length)); /* receiving the answer string length*/
s=(char*)malloc(length*sizeof(char)); /* receiving the string with the date */
printf ("Date from server = %s\n", s);
}
free(s);
Note what happens if 'answer' is not equal to 1002 -- you're calling free() on an uninitialized value. That is likely the cause of the error you are seeing. (This same mistake is present in both programs)
Refering the server code:
Here you allocate memory to s:
s=(char*)malloc(sizeof(asctime(timeinfo))*sizeof(char));
Here you overwrite the pointer with the value receive from asctime() so the original value returned by malloc() is lost introducing a memory leak:
s=asctime(timeinfo);
Here you then try to free what had been received from asctime(), which is a reference to static memory and gherefore cannot be freed.
free(s);

getsockname() c not setting value

I'm trying to get the local IP used for a connection established. However, for some reason, I'm unable to use getsockname because it never sets any data in my sockaddr.
int fd = socket(/* params */);
int len;
struct sockaddr_in _self;
/* Connection code, I know the connection succeeds and I've tested */
memset(&_self, 0, sizeof (struct sockaddr_in));
getsockname(fd, (struct sockaddr *) &_self, &len);
printf("%s\n", inet_ntoa(_self.sin_addr);
However, when the program gets to printf, it always terminates due to a 'Segmentation fault', which I think is when it tries to access memory that it hasn't set (am I correct in this assumption?) If so, does that mean that getsockname is failing?
You have to initialise len to be the maximum allowed size before calling getsockname() (ie, the size of the structure). This length value is them modified by the call to contain the actual length.
You should also ensure that the socket descriptor has been bound. Your test seems to indicate it's for an established session but the code is unclear in that it only contains a socket() call.
As a baseline, use the following program:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main (void) {
int fd = socket (AF_INET, SOCK_STREAM, 0);
struct sockaddr_in _self;
int len = sizeof (_self);
memset (&_self, 0, len);
bind(fd, (struct sockaddr *) &_self, len);
memset (&_self, 42, len);
getsockname (fd, (struct sockaddr *) &_self, &len);
printf ("%s\n", inet_ntoa (_self.sin_addr));
return 0;
}
This outputs 0.0.0.0 as expected.

TCP client/server printing extra strings

I am trying to make a program with a server and multiple clients can connect to that server through the predefined port nummber. By the way, this is TCP in C. I have the following server code below:
SERVER CODE:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int listenfd , connfd , c , *new_sock;
struct sockaddr_in servaddr , cliaddr;
listenfd = socket(PF_INET , SOCK_STREAM , 0);
if (listenfd == -1)
puts("SOCKET CREATION ERROR!");
puts("Socket created");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(54321);
bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr) );
listen(listenfd,2);;
c = sizeof(struct sockaddr_in);
while( (connfd = accept(listenfd, (struct sockaddr *)&cliaddr, (socklen_t*)&c)) ){
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = connfd;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("Thread Error Connection");
return 1;
}
puts("Handler assigned");
}
if (connfd < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char client_message[51]="";
while( (read_size = recv(sock , client_message , 50, 0)) > 0 )
{
printf("%s",client_message);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
free(socket_desc);
return 0;
}
CLIENT CODE:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
socklen_t len = sizeof(servaddr);
char mesg[1024];
if(argc!=2){
printf("Usage: %s <ip_addr>\n",argv[0]);
exit(1);
}
sockfd = socket(PF_INET,SOCK_STREAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(54321);
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while(1){
fgets(mesg,sizeof(mesg),stdin);
sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
}
close(sockfd);
return 0;
}
I get the following output:
Socket created
Connection accepted
Handler assigned
Hello There!
What could be the problem?
I don't know?
the problem?
Hey!
't know?
the problem?
I typed in the following strings in the client terminal:
Hello There!
What could be the problem?
I don't know?
Hey!
The problem is when I typed the third string, the output is the third string with some parts of the second string still appearing. What could be the problem? Thanks!
TCP is stream oriented.
You can not expect that write() writes as much data as you told it to write, as well as you can not expect that read() reads as much data as you told it ro read.
This both put together means that to transfer N bytes via a socket the number of calls to read() does not necessarily needs to match the number of calls to write().
And following this conclusion the only thing the reader could know is how much it read from the moment on it was created.
The only two synchronisation points between reader and writer are the creation and the shutdown of the connection. The period one can call a session.
So if one wants to transfer multiple blocks of data having different sizes unknown to the reader during one session one is in the need to establish additional synchronisation points during the session, that make the read detect that a full block had been received.
Doing so is implementing some sort of protocol.
There are endless possiblities how the protcol could look like. The detailed design of the protocol depends on the use cases which shall be covered by the application.
Assuming only text data shall be transfered a simple protocol could be to terminate each data block by a \n.
The writer loops around write() until all data is sent and finally sends a \n.
The reader loops around read() until a \n had been received.
C strings are null terminated. You're not sending the zero byte that would terminate your string in your recieving buffer, so your printf will print out all characters it find until it reaches some zero byte. strlen returns length of string in number of characters, but without counting the zero byte at the end.
Try to change line in your client:
sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
Into:
sendto(sockfd,mesg,1+strlen(mesg),0,(const struct sockaddr *)&servaddr,len);

simple TCP client serve model in C : client not recieving

im making a simple TCP client-server in c and im trying to send a message from the client to the server, but im having some problems with it.
The server does send the message (integer value > 0) but the client is unable to receive it (integer value > 0)
here is the code:
Client
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "hello";
struct sockaddr_in serv_addr;
s_id = socket (AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons (1156);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(s_id,(struct sockaddr *) &serv_addr, sizeof (struct sockaddr));
int r = recv (s_id, (char *) msg, 9, 0);
printf("%d \n", r );
printf("%s \n", msg );
return 0;
}
Server:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main()
{
int s_id;
char *msg = "connected";
struct sockaddr_in my_addr, remote_addr;
s_id = socket (PF_INET,SOCK_STREAM,0);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(1156);
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(s_id,(struct sockaddr *) &my_addr, sizeof(struct sockaddr));
listen (s_id,5);
int size = sizeof (struct sockaddr_in);
int new_sd = accept (s_id, (struct sockaddr *) &remote_addr, &size);
int s= send(new_sd, (void *)msg, 9, 0);
printf("%d \n", s );
return 0;
}
The outputs i get (after first starting the server, and then the client) are
server side: 9
client-side: -1
hello
I am using Ubuntu 11.04 and the gcc compiler.
I hope someone out there can help.
Thank you
Umar
char *msg = "hello";
This is a string literal. It's a constant, and you can't change it.
int r = recv (s_id, (char *) msg, 9, 0);
And there you're trying to write to it.
Change your declaration to:
char msg[20];
memset(msg, 0, sizeof(msg));
If you make that change, your code works as expected.
In C you're going to have to allocate and manage buffers - there's no free lunch :)
Also take note of the other answer from Nikolai N Fetissov - you really should be checking return codes from all the system calls.
You never check for errors after any of the system calls. All of socket(2), connect(2), etc. return -1 on failure, then you can print the error description with, say, perror(3) function. Each system call manual page lists possible errors.
Edit 0:
The real problem is probably what Brian points out - you are trying to receive data into read-only memory on the client. Does it die with a segfault?

Resources