ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
The server you use exhibits strange behaviour by only allowing one message to be sent per connection.
Anyhow, concerning the shutdown problems, I've never used shutdown() for any purpose; I believe the close() should suffice.
Btw, you can determine if indeed the server has "kicked" your client off by performing another recv(). If the return value is zero (0), then it's a sure bet that you have been disconnected.
P.S. Please format any code you post using the PHP or CODE tags. These tags need to be specified within square brackets [].
Last edited by dwhitney67; 02-13-2009 at 09:01 AM.
Initializing the buffer to all nulls, as I have shown in my example, was not a big effort. In fact, it is wise to always initialize variables (when they are declared).
If I'm going to initialize a buffer before reading into it or filling it with data for writing, I'll initialize it to something crazy like 0x5A in each byte, and I'll do so before each read() (or before filling it for a write()). That gives me a better (but not 100% rock-solid) indication at debugging time of how much of the buffer I've used.
Filling the buffer with NUL bytes can sometime mask other bugs. I could, for example, have code that plants a NUL byte at the end of what I've just read, and I could be planting that NUL byte in an entirely wrong address (thus yielding erratic, hard-to-reproduce trashing of other data), and I'd never know that if I've initialized the buffer with NUL, but I would if I had used 0x5A.
Thanks. But the close() doesn't work. I tried shutdown() and also failed.
Quote:
Originally Posted by dwhitney67
The server you use exhibits strange behaviour by only allowing one message to be sent per connection.
Anyhow, concerning the shutdown problems, I've never used shutdown() for any purpose; I believe the close() should suffice.
Btw, you can determine if indeed the server has "kicked" your client off by performing another recv(). If the return value is zero (0), then it's a sure bet that you have been disconnected.
P.S. Please format any code you post using the PHP or CODE tags. These tags need to be specified within square brackets [].
void displayMenu() { printf("Please choose the operation:\n\n"); printf("\t1. Read voltage configuration\n"); printf("\t2. Read temperature & fan configuration\n"); printf("\t3. Write voltage configuration\n"); printf("\t4. Write temperature & fan configuration\n"); printf("\t5. Read voltage data\n"); printf("\t6. Read temperature data\n"); printf("\t7. Read fan revolution data\n"); printf("\t8. Read switch status\n"); printf("\t9. Read system monitor status\n"); printf("\t0. Exit\n"); }
dwhitney67, thank you so much. The code looks much better. The problem is that the close() still didn't work for me, neither shutdown(). I should ask the manufacturer about it. Thanks.
I am pretty sure you don't need the shutdown command (you could read the man pages to find out what they do).
When you will be using the socket multiple times like in this case it would be better to move the socket setup (socket() connect() etc.) to the main function and then pass the sock descriptor(sd) to you function(io_operation). Then right before you exit out of the main function close the socket. Since you are continually calling your helper function and re-setting up the socket it would be better to move the code to the main function and just leave the socket open the entire time.
This will also save you coding on the server side...cause if you continually open new socket/connections to the server the server will continually have to accept these new connection. If you only open and connect a single socket that you use throughout the program your server will just have to accept this single connection.
Also why to you say that close and shutdown are not working for you? Are they returning errors? Or are you not able to reopen a connection the second time? If the later it might be because the system doesn't release ports right away even after they are no longer being used. So you could either just open one socket and use that the entire time or there is a socket option (setsockopt) the you can set right after calling the socket() function to allow reuse of the port bindings but I don't remember the option off hand.
Also why to you say that close and shutdown are not working for you? Are they returning errors? Or are you not able to reopen a connection the second time? If the later it might be because the system doesn't release ports right away even after they are no longer being used. So you could either just open one socket and use that the entire time or there is a socket option (setsockopt) the you can set right after calling the socket() function to allow reuse of the port bindings but I don't remember the option off hand.
What you are writing about above applies to the server side; and from what I understand, the OP is using a COTS server application, for which she does not have the privilege to modify.
The option you are referring to is SO_REUSEADDR that is passed to setsockopt().
Anyhow, since we don't know anything about the server that the OP is using, all I can assume from what the OP describes, is that the issue lies there.
I've taken her original code, and the refactored code I posted earlier that was based on her work, and in each case, both behave well with a server application that I developed that performs the basic operations of accepting connections, receiving client messages, and then sending back a response containing the client message. When the client disconnects, the server is notified of such, and handles it appropriately.
Last edited by dwhitney67; 02-14-2009 at 05:06 AM.
First choose the option, then connect, send, recv, close finally. But the close() and shutdown() doesn't work.
shutdown after close probably does nothing since it's supposed to close the descriptor in addition to severing the connection; I'm sure close invalidates the descriptor for the shutdown call.
Quote:
Originally Posted by dwhitney67
Anyhow, concerning the shutdown problems, I've never used shutdown() for any purpose; I believe the close() should suffice.
I encountered shutdown because of this sort of problem, plus problems rebinding to the same port in cases where both ends haven't called shutdown on a connection associated with the port. close only closes the descriptor, then it's up to the kernel to get around to destroying the connection. You might not have encountered situations where this was a problem, but I have, which is why I use it.
ta0kira
The binding of a port is done by the server, not the client. I suspect that the vendor that Jane2008 mentioned, is not divulging the proper protocol for the server application, or they wrote a piss-poor application.
The binding of a port is done by the server, not the client.
Yes, I know that. What I'm saying is that, despite a server closing a socket descriptor bound to a port and the process exiting, sometimes the port won't be available if a client still hasn't terminated the connection (even though the server no longer exists,) which can sometimes happen if only close is used (but more commonly with a hung process.) This is something I've seen enough that the only reasonable cause is a socket left open. Whether or not this is the cause of OP's problem isn't the point; properly shutting down the connection eliminates it as a possibility.
ta0kira
Thanks for all your help.
The module broken several days ago and i just got a new one yesterday.
I tried to use socket, connect, send, and recv in a loop but it fails.
It seems that the socket only works for the first time. After that, I have to ctrl+c to terminate the program and reset the module.
Also I tried to use socket, after that a loop contains connect, send, and recv. This time the connect only works for the first time. After that, a error occured 'transport endpoint is already connected'.
Any suggestion would be appreciated.
Thanks.
I also tried socket, connect, then a loop containing send, recv.
The send works well while recv fails after the first time.
The return value of recv() is 0.
At the second time the error is:
recv: success (but still failed)
After that, the error is:
recv : Illegal seek
I think this method doesn't work because the module only support once message send per connection.
It seems that the server is still the issue, not your client application. Why don't write your own server so that you can test your client?
The following should help get you going:
Code:
...
int main(int argc, char** argv)
{
/* use port 9000, unless another port number is given on the cmd line */
const unsigned short port = (argc > 1 ? atoi(argv[1]) : 9000);
/* create the socket */
int sd = socket(AF_INET, SOCK_STREAM, 0);
assert(sd > 0);
/* Setup info about the host/port */
struct sockaddr_in socketaddr;
memset(&socketaddr, 0, sizeof(socketaddr));
socketaddr.sin_family = AF_INET;
socketaddr.sin_port = htons(port);
socketaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* bind to the port */
int rtn = bind(sd, (struct sockaddr*) &socketaddr, sizeof(socketaddr));
assert(rtn == 0);
/* listen on the socket */
rtn = listen(sd, 5);
assert(rtn == 0);
for (;;)
{
/* wait for a client connection */
int c_sd = accept(sd, 0, 0);
for (;;)
{
char buf[256] = {0};
int bytesRecv = recv(c_sd, buf, sizeof(buf), 0);
if (bytesRecv <= 0) /* error or client disconnected */
{
close(c_sd);
break;
}
printf("Received %d byte(s): %s\n", bytesRecv, buf);
/* add add't code if you need to send a reply back to the client */
}
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.