'Use semaphores for handling sockets in C
I have the following piece of code:
SOCKET sock = open_socket(szListenHost, iListenPort);
if (sock > 0) {
SOCKET client;
struct sockaddr_in peeraddr;
T_socklen len = sizeof (struct sockaddr_in);
char buf[1024];
sin.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
sin.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
sin.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
sin.hStdError = GetStdHandle(STD_ERROR_HANDLE);
sin.wShowWindow = SW_HIDE;
dwCreationFlags = CREATE_NO_WINDOW;
CreateProcess(NULL, buf, NULL, NULL, FALSE, dwCreationFlags,
NULL, NULL, &sin, &pin);
memset(&peeraddr, 0, sizeof (struct sockaddr_in));
client = accept(sock, (sockaddr*)&peeraddr, &len);
if (client > 0) {
rv = message_loop(client);
}
closesocket(sock);
}
As you can see, this is opening a TCP socket for interrogation reasons.
The situation is the following: my client application (who is opening those sockets) might need to open different TCP sockets simultaneously, which might cause problems.
In order to avoid those problems, I would like to ask whether the socket is already opened. If yes, then wait until the socket is freed again and then try again to open the socket.
I have understood that semaphores can be used for this intention, but I have no idea how to do this.
Can anybody help me? Thanks
First I'd like to thank John Bollinger for your fast response. Unfortunately their seems to be as misunderstanding: I am not looking for a way to open one socket different times simultaneously, but I am looking for a way to be noticed when a socket becomes available. In fact, I would like to do the following: Instead of:
SOCKET sock = open_socket(szListenHost, iListenPort);
I could do this (very basically):
while (open_socket(szListenHost, iListenPort)) {sleep (1 second;)}
This however means that I would need to poll the socket constantly, creating quite some overhead. I have heard that semaphores could solve this issue, something like:
SOCKET sock = handle_semaphore(open_socket(szListenHost, iListenPort));
and the "handle_semaphore" would then be a system that automatically waits for the socket to be released, so that immediately my client process can open the socket, without the risk of being pushed behind. As you can see, it's all about rumours but I have no idea how to realise this. Does anybody know whether indeed semaphores can be used for this intention and if possible, give me some guidance on how to do this?
Thanks
Solution 1:[1]
Meanwhile the situation has changed, and I now have been able to add semaphores to my socket related application. Generally this works but sometimes the application hangs.
After some debugging I have understood that the application hangs at the moment I launch following C command:
printf("Will it be accepted?\n");
fflush(stdout);
memset(&peeraddr, 0, sizeof (struct sockaddr_in));
client = accept(sock, (sockaddr*)&peeraddr, &len);
printf("It is accepted, the client is %d.\n",client);
=> I can see in my debug log "Will it be accepted?", but I don't see "It is accepted, ...".
I admit that I am quite violent while testing (sometimes I stop debugging sessions without giving the application to close the socket, ...), but you can imagine customers behaving in the same way, to the application needs to be sufficiently robust.
Does anybody know how I can avoid the "accept" command going into such an infinite loop?
Thanks
Solution 2:[2]
Once opened, a socket cannot be reopened, even if it is closed. You can create a similar, new socket, though. Either way, it is difficult to reliably determine whether a previously-opened socket has been closed, except by closing it.
In any case, the usual paradigm does not require the kind of coordinating mechanism you ask about. Normally, one thread of one process would open the socket and have responsibility for accepting connections on it. If it is desired that the program be able to handle more than one connection at a time, then each time that thread accepts a new connection, it assigns that connection to be handled by another thread or process -- typically, but not necessarily, a newly-created one.
It is not usually necessary or desirable to open a new socket to receive additional connections at the same address and port. Usually you just use the same socket, without caring about the state of any connections already established via that socket. You could, perhaps, use a semaphore to coordinate multiple threads of the same process receiving connections from the same socket, but I would avoid that if I were you.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | John Bollinger |