0

I've been writing a server and every time I quit it and re-open it, it seems to fail to bind to the socket. I'm connecting 2 clients and then disconnecting them with close() before I shut down the server, I also then quit the clients before opening the server just in case, however it still seems to fail and I have to restart my computer. Here is my code:

listenSocket = device = app = 0;

struct sockaddr_in server_addr;

char buffer[1024];

listenSocket = socket(AF_INET, SOCK_STREAM, 0);

memset(&server_addr, '0', sizeof(server_addr));
memset(buffer, '0', sizeof(buffer));

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(35565);

//bind the socket
if (bind(listenSocket,(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {

    NSLog(@"Error binding to socket");
}


if (listen(listenSocket, 5) == -1) {

    NSLog(@"Failed to listen");

}

//launch thread for console
[NSThread detachNewThreadSelector:@selector(console) toTarget:self withObject:nil];

NSLog(@"Starting server");

//socket open, ask for clients
while (true) {

    int client = -1;

    if (!device || !app)
        client = accept(listenSocket, (struct sockaddr*)NULL, NULL);

    //handshake omitted for length
}

And the code to close the server:

close(listenSocket);
        close(device);
        close(app);
        NSLog(@"Clean");

Is there something I'm doing wrong? Any help would be appreciated. Thanks.

EDIT: Here is my error checking code:

NSLog(@"%s",strerror(errno));
int e = bind(listenSocket,(struct sockaddr*)&server_addr, sizeof(server_addr));
NSLog(@"%s",strerror(errno));
BlueSpud
  • 1,555
  • 3
  • 19
  • 44
  • And the programming language is? – bmargulies Aug 09 '15 at 00:01
  • @EJP It will print out failed to bind to socket, and no client can connect. – BlueSpud Aug 09 '15 at 00:06
  • @bmargulies its a mix of C, C++ and Objective-C. – BlueSpud Aug 09 '15 at 00:07
  • Useless. We can see for ourselves that you log that message when you get an error on `bind()`. However *that is not the error.* It is just some futile message of your own devising. The error is contained in `errno`, and can be printed via `perror()` or `strerror()`. *That's* what we need to see, and indeed that's what you should have been logging in the first place. NB I started typing this comment before you responded, as I know from long experience what to expect. – user207421 Aug 09 '15 at 00:08
  • @EJP using strerror(errno), it gives "No such process" – BlueSpud Aug 09 '15 at 00:15
  • Sigh. You need to call`perror()` or `strerror()` *before calling any other system calls.* Otherwise the value of `errno` has changed, in this case to something that is obviously irrelevant. NB You haven't even reported your own message correctly. It wasn't 'failed to bind to socket', it was 'error binding to socket'. You can't be that sloppy in this business. NB 2 You aren't binding *to* a socket, you are binding a socket to an address:port. – user207421 Aug 09 '15 at 00:17
  • @EJP updated the question to what I think you mean by using the calls. It prints out: "No such file or directory" and then "Address already in use" – BlueSpud Aug 09 '15 at 00:20
  • Double sigh. The value of `errno` etc is irrelevant unless the prior system call returned -1. This is all Unix Systems Programming 101 stuff. – user207421 Aug 09 '15 at 00:22
  • @EJP I've never used these calls in the past, can you give an example? Obviously I'm not understanding what you're saying. And bind() is returning -1. – BlueSpud Aug 09 '15 at 00:24
  • 1
    possible duplicate of [Socket options SO\_REUSEADDR and SO\_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?](http://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t) – bmargulies Aug 09 '15 at 00:24
  • `bind()` can't possibly cause a 'no such process' error. See the *man* page. *Ergo* you are logging it wrongly. In the edit you are logging `strerror()` unconditionally, not if and only if `bind()` returns -1. I can only comment on the code you actually posted. – user207421 Aug 09 '15 at 00:33

2 Answers2

3

You need to set the SO_REUSEADDR option. Otherwise, once you grab the port in a process, there is a significant timeout before the kernel will let you have it again. Much detail to be found in an existing question; I've voted to close as a duplicate.

Community
  • 1
  • 1
bmargulies
  • 97,814
  • 39
  • 186
  • 310
0

I had a similar problem which was caused by another process holding on to the ports. Killing that process solved the problem.

UserX
  • 485
  • 5
  • 12