C, Bind faild: `Address Already in Use` - c

I am writing a client-server program in C. I am getting an error in Bind function says: Address Already in Use. So I tired to use memset() and I got error says: Invalid Argument. Finally, I looked for similar questions on here, and some of them suggesting the use of setsocketopt() function. I used it and I am getting error says:
/tmp/ccBNsJtU.o: In function main:
socket.c:(.text+0xd0): undefined reference to setsocket
collect2: error: ld returned 1 exit status
I looked at almost-if-not all the similar questions even in different programing languages. Now I am stuck. Do I have to use setsocket() and if I do, is it causing a problem in my code? Or I don't have to use it and the problem is somewhere else? Could the problem be in the client or the server functions where I listen and send messages? This is the part of the code where the bind() and setsocket() functions are:
int main (void) {
int sl, sa, bn, erro, lis;
int status;
//server log socket
struct sockaddr_un server = {AF_UNIX, "log_server"};
sl = socket (AF_UNIX, SOCK_STREAM, 0);
if(sl < 0) {
perror("Faild to create socket - in main");
exit(1);
}
//I added this part
if (setsocket(sl, SOL_SOCKET, SO_REUSEADDR, &server, sizeof(server)) == -1) {
perror("setsocket - in main");
exit(1);
}
bn = bind (sl, (struct sockaddr *)&server, sizeof(server));
if(bn < 0){
perror("Faild to bind - in main");
exit(1);
}
lis = listen (sl, 1); //to be changed to 4
if (lis < 0) {
perror("Faild to listen - in main");
}

"Address already in use" typically means that some other socket is already bound to the given port. This could mean that there's a running program actively listening on that port, or it could mean that a prior instance of your program which is no longer running still has some socket resources open in the OS.
In the latter case, a call to setsockopt (not setsocket) with the SO_REUSEADDR parameter will address this. The fourth parameter should be a pointer to a char whose value is 1, while the fifth parameter should be sizeof(char).

For the users who are facing the problem in bind() function that generate error of the type: Address Already in Use. Here is one tip:
My problem was because the program ran and an address being used by the bind() and then the program generated errors and stopped/terminated. So the unlink() function at the end of the code had no chance to do its job and the address kept in use. So simplest way is at the beginning of the function unlink the processes you are going to bind later in the function.
This seems like so simple and I don't know if it is a good practice but it worked for my purpose.

Related

Socket connection in Linux

I just got a error from connect API in linux.
I knew 'connect' will return zero if connection is successful, I got return value "3"
is it error code? or is there something else what don't know?
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
I got value 3 from sock.
To get the return value of connect(), it is most straight forward to use a variable that is used as the left hand side of an assignment.
int result = connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
printf("connect returned: %d\n", result);
sock must be a socket, and was assigned a file descriptor number as a result of a call to socket(). Most UNIX APIs that return a new file descriptor will return the lowest available one. A program usually starts off with descriptors 0, 1, and 2 already in use (for STDIN, STDOUT, and STDERR). So, it is not unexpected that socket() returned 3.
In linux systems (and posix generally), you can use perror function to know the failure reason:
if (0 != connect(...))
{
perror("connect");
}
see man perror

c- recvfrom error 22

Okay first here is the code:
int recvMast_sock;
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len;
if ((recvMast_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
critErr("listen:socket=");
}
fillSockaddrAny(&serv_addr, UDP_NODE_LISTEN_PORT);// fills the sockaddr_in works fine elsewhere
if ((bind(recvMast_sock, (struct sockaddr*) &serv_addr, sizeof serv_addr)) < 0)
{
critErr("listen:bind recv_mast_sock:");
}
recvReturn_i = recvfrom(recvMast_sock, &recvBuff[0], (size_t)1, 0, (struct sockaddr*) &cli_addr, &cli_len);
if(recvReturn_i <0)
printf("recv error%d\n",errno);
critErr is a function to handle errors which also includes a print of the error and an exit.
This runs in a thread, if this is of any relevance. If I compile and run this on a Zedboard (ZYNQ-7000 SoC) which has an ARM Cortex A9 and Linaro Linux (based on precise Ubuntu). It prints error 22 but still has the received value in recvBuff[0].
Running this in my VM with xubuntu it works fine.
Error 22 equals EINVAL which is described as Invalid argument.
In the manpage of recvfrom(2) it states EINVAL means that the MSG_OOB flag is set but I don't use any flags (passing 0).
Before leaving on friday I started an apt-get upgrade because I hope it is a faulty library or something like this. I can check back at monday but maybe someone here has another idea what is wrong.
You need to initialize cli_len before passing it to recvfrom():
cli_len = sizeof(cli_addr);
You are not initializing it, so it has a random value. If that value happens to be < sizeof(cli_addr), recvfrom() can fail with EINVAL, or at least truncate the address, because it thinks cli_addr is not large enough to receive the client address. If the value is vastly larger than sizeof(cli_addr), recvfrom() might consider the buffer to be outside of the valid memory range.
You have to tell recvfrom() how large cli_addr actually is. This is clearly stated in the documentation:
The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.
So you have to initialize cli_len with the total size of cli_addr before calling recvfrom(), then recvfrom() updates cli_len with the size of the address that was actually written into cli_addr. cli_addr can be larger than the address, for instance when using a sockaddr_storage structure to accept either IPv4 or IPv6 addresses on a dual-stack socket. In the example in the question, an IPv4 socket is being used, so cli_len must be initialized to a value >= sizeof(sockaddr_in).
This was not caused by the OS or the architecture. The function was not called on the x86-system because of a blocked mutex. So I didn't got the error there.
The problem was that I passed the socket to this function from 'main' (which i did not state in the question because I thought it was irrelevant, my bad...)
In 'main' I used it and used it in this function. Even though it was mutually exclusive, there was this error.
Remy's answer was also relevant but not a solution to the problem. Not setting cli_len beforehand just leads to a cut of sockaddr if its too small. No error was generated for that.

Get Local Port used by Socket

I need to get the local port used by a (client) socket.
It was my understanding that Windows Sockets performs an implicit bind function call, therefore getsockname() after sendto() should provide the assigned port. However, it always sets 0 as the port number. Am I missing something?
ex:
if (sendto(sockfd, ...) != SOCKET_ERROR)
printf("Sent\n");
if (getsockname(sockfd, (struct sockaddr*)&sin, &sinlen) != SOCKET_ERROR)
printf("port = %u\n", ntohs(sin.sin_port);
else
printf("Error");
//result: Sent, port = 0
Problem solved with a restart of the computer. Still unknown as to the actual cause, but at this point I'm just happy it's working.
If anyone has an idea for fixing the issue without a restart (for future readers), feel free to post.
The only ambiguity I can see in your example code is what size you assigned to sinlen before calling. (you do not show it) If you are using winsock, it should be defined, and assigned int sinlen = sizeof(sin);
I used this code on my system, and it returns a non-zero value for the port I am connecting through:
struct sockaddr_in sin;
int len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
//handle error
else
printf("port number %d\n", ntohs(sin.sin_port));
By the way, The ntohs function function returns the value in host byte order. If [ sin.sin_port ] is already in host byte order, then this function will reverse it. It is up to [your] application to determine if the byte order must be reversed. [text in brackets are my emphasis]
In answer to comment question ( getsockname() ):
The function prototype for getsockname():
int getsockname(
_In_ SOCKET s,
_Out_ struct sockaddr *name,
_Inout_ int *namelen //int, not socklen_t
);
For more discussion on socklen_t
Edit (address possible approach to re-setting sockets without rebooting PC.)
If winsock API calls cease to work predictably, you can re-start sockets without rebooting the PC by using WSAStartup and WSACleanup (see code example at bottom of link for WSAStartup)
You say you want to know the LOCAL port, but your line
sendto(sockfd, ...)
implies sockfd is the REMOTE descriptor. Your later code may therefore give you info about the REMOTE port, not the LOCAL one. 'sockets' are not both ends, meaning one connection. A socket is one end, meaning the IP and port number of one end of the connection. The first parameter of your getsockname() is not a reference or a pointer, it is therefore not an output from the function, but an input. You're telling the function to use the same socket descriptor that you just sent to, ie. the remote one.
Formatting error. ntohs() returns unsigned short so the format should be %hu, not %u or %d. If you grab too many bytes they are not the port.
Answer. After using sendto() try using gethostname() then getaddrinfo() on the name that comes back. Note: the addrinfo structures you get back will give you struct sockaddr pointers which you will need to re-cast to struct sockaddr_in pointers to access the local port number.
To find the local port number the kernel dreamed up when you issued a sendto() function perhaps you could write a routine to parse the output from the (gnu linux) commands 'ss' or 'netstat'. (Not sure if these are POSIX compatible.) Or maybe you could access /proc/net if you have the privilege.

Accept() returns a reference to stdout (1) when using pthreads

Original post:
I have been learning network programming from Beej's Guide to Network Programming for school. I'm currently working on a prototype for myself to communicate among multiple connections concurrently by using threads and I/O multiplexing. I'm getting a problem where when I receive a connection and call accept() to return a new file descriptor to "new_fd" instead of returning a new file descriptor it returns 1. This doesn't make sense to me because I'm not closing stdout anywhere in my code and accept() is supposed to return a reference to the socket as a new file descriptor, and as far as I know threads share the same file descriptors across a single process so it shouldn't be a problem that I have it threaded. I thought that the problem might be that I was connecting from my own computer using the loopback, but when I connected by referencing my ip address or another computer it also resulted in the same error of returning a fd of 1. I have no idea where to look anymore to solve this issue
Original posted code:
http://pastebin.com/APQYjxg9
(I had posted all of my code)
Editing this for clarity. There were two things wrong with my code. The first one was pointed out by R.. immediately and that code snippet is here:
if (value = pthread_create((chat+chat_count), NULL, chatDaemon, (void *) &new_fd) != 0)
{ -snip- }
void * chatDaemon(void * fd)
{
int my_fd = *((int *)fd);
-snip-
}
I later figured out what went wrong and posted my answer. Code snippet for that here:
if (new_fd = accept(listen_fd, (struct sockaddr*) &(remoteHost), &addrlen) != -1) { -snip-}
Revisiting this after far too long. The lack of synchronization that R.. pointed out would have been a problem for this, however it was not causing the problem that I was experiencing. It was simply a small syntactical error with the accept logic so I originally had
if (new_fd = accept(listen_fd, (struct sockaddr*) &(remoteHost), &addrlen) != -1)
which as written evaluates and returns the result of the boolean check on accept to new_fd, which was always returning 1 for true. I did not realize at the time that c would order the operations that way and I fixed it with parentheses.
if ((new_fd = accept(listen_fd, (struct sockaddr*) &remoteHost), &addrelen)) != -1)
Your problem seems to be a lack of synchronization reading *(int *)fd in chatDaemon. fd is a pointer to the local variable new_fd in main, which could be modified before or while chatDaemon is reading it, invoking undefined behavior. You either need to allocate storage for the int to store the fd and have chatDaemon free it, or (preferable) just cast it to void * and back rather than trying to pass the fd by reference.

How do I communicate between a server and a client using sockets? [C]

I am doing a Unix, C assignment. I am creating a Server and a Client which will interact with each other. I am pretty sure I have set up the basic framework but I when I try to send/receive messages, it doesn't work.
Here is the while loop code for the server, I tried to show only the relevant code:
while(1) {
clntAdrLen = sizeof(clntAddr);
clntFd = accept(srvrFd, (struct sockaddr*)&clntAddr, NULL);
if (fork() == 0) {
send(clntFd, "YourMessage", 12, NULL);
close(clntFd);
exit(0);
} else {
close(clntFd);
}
}
And here is the code for client:
do {
result = connect(srvrFd, (struct sockaddr*)&srvrAddr, srvrLen);
if(result==-1) {
sleep(1);
}
recv(srvrFd, buf, sizeof(buf), NULL);
printf("%s", buf); //here I try to print the message sent by server
} while (result==1);
When I run both server and client, It should print "YourMessage". Instead it prints:
N0�,
Am I just doing it wrong? Thanks
I guess your problem is in accept function.
As said in Linux Programmer's Manual:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; on return it will contain the actual size of the peer address.
Do yourself a favor and buy yourself "UNIX Network Programming" ISBN-10: 0139498761
There is way more to socket programming than meets the eye.
For one, how are you going to know on the receiving end how long the sent string is? Are you going to presume it's always 12, in most practical examples it won't be the same every time.
Are you going to read until you hit an end of string, or are you going to send an integer at the start to tell the reader what the length is?
If you use an integer do you know about endian-ness?
Are you really going to learn anything if we do your homework for you? Presumably you're in college and paying your tuition. Are you there to pass or are you there to learn?

Resources