For THIS reason, I want to try something new - close the socket using some system call.
The situation in two words - can't set query timeout of the mysql library (the C API, refer to the link for more info), so I want to try closing the socket to see how the library will react. Probably this is not a good idea, but still wanna try it.
Here's what I've done - there's another started thread - a timer. So, after a specific timeout (let's say 10 second), if there's no response, I want to close the socket. The MYSQL struct has member net, that is also a struct, and holds the fd. But when I try to do this:
shutdown( m_pOwner->m_ptrDBConnection->m_mysql.net.fd, SHUT_RDWR );
close( m_pOwner->m_ptrDBConnection->m_mysql.net.fd );
nothing happens. The returned values from shutdown and close are 0, but the socket is still opened (because after 60sec waiting, there's a returned result from the DB, that means that the mysql client is still waiting for response from the DB.
Any ideas?
Thanks
EDIT - Yes, there's a running transaction, while I'm trying to close the socket. But this is the actual problem - I cannot terminate the query, nor to close the connection, nothing, and I don't wanna wait the whole timeout, which is 20min and 30 sec, or something like this. That's why I'm looking for a brute-force.. :/
Just a shot in the dark, but make sure you cancel/terminate any running transactions. I'm not familiar with the MySQL C API, but I would imagine there is a way to check if there are any active connections/queries. You may not be able to close the socket simply because there are still things running, and they need to be brought to some "resolved" state, be that either committed or rolled back. I would begin there and see what happens. You really don't want to shutdown the socket "brute force" style if you have anything pending anyway because your data would not be in a reliable "state" afterwards - you would not know what transactions succeeded and which ones did not, although I would imagine that MySQL would rollback any pending transactions if the connection failed abruptly.
EDIT:
From what I have found via Googling "MySQL stopping runaway query", the consensus seems to be to ask MySQL to terminate the thread of the runaway/long-running query using
KILL thread-id
I would imagine that the thread ID is available to you in the MySQL data structure that contains the socket. You may want to try this, although IIRC to do so requires super user priviledges.
EDIT #2:
Apparently MySQL provides a fail-safe mechanism that will restart a closed connection, so forcefully shutting down the socket will not actually terminate the query. Once you close it, MySQL will open another and attempt to complete the query. Turning this off will allow you to close the socket and cause the query to terminate.
The comments below show how the answer was found, and the thought process involved therein.
It looks like you are running into an issue with the TCP wait timer, meaning it will close eventually. [Long story short] it is sort of unavoidable. There was another discussion on this.
close vs shutdown socket?
As far as I know, If shutdown() and close() both return 0 there's no doubt you had successfully closed a socket. The fact is that you could have closed the wrong fd. Or the server could not react properly to a correct shutdown (if so, this could be considered a bug of the server: no reason to still wait for data incoming). I'd keep looking for a supported way to do this.
Related
I am currently working on a server application in C++. My main inspirations are these examples:
Windows SDK IOCP Excample
The I/O Completion Port IPv4/IPv6 Server Program Example
My app is strongly similar to these (socketobj, packageobj, ...).
In general, my app is running without issues. The only things which still causes me troubles are half open connections.
My strategy for this is: I check every connected client in a time period and count an "idle counter" up. If one completion occurs, I reset this timer. If the Idle counter goes too high, I set a boolean to prevent other threads from posting operations, and then call closesocket().
My assumption was that now the socket is closed, the pending operations will complete (maybe not instantly but after a time). This is also the behavior the MSDN documentation is describing (hints, second paragraph). I need this because only after all operations are completed can I free the resources.
Long story short: this is not the case for me. I did some tests with my testclient app and some cout and breakpoint debugging, and discovered that pending operations for closed sockets are not completing (even after waiting 10 min). I also already tried with a shutdown() call before the closesocket(), and both returned no error.
What am I doing wrong? Does this happen to anyone else? Is the MSDN documentation wrong? What are the alternatives?
I am currently thinking of the "linger" functionality, or to cancel every operation explicitly with the CancelIoEx() function
Edit: (thank you for your responses)
Yesterday evening I added a chained list for every sockedobj to hold the per io obj of the pending operations. With this I tried the CancelIOEx() function. The function returned 0 and GetLastError() returned ERROR_NOT_FOUND for most of the operations.
Is it then safe to just free the per Io Obj in this case?
I also discovered, that this is happening more often, when I run my server app and the client app on the same machine. It happens from time to time, that the server is then not able to complete write operations. I thought that this is happening because the client side receive buffer gets to full. (The client side does not stop to receive data!).
Code snipped follows as soon as possible.
The 'linger' setting can used to reset the connection, but that way you will (a) lose data and (b) deliver a reset to the peer, which may terrify it.
If you're thinking of a positive linger timeout, it doesn't really help.
Shutdown for read should terminate read operations, but shutdown for write only gets queued after pending writes so it doesn't help at all.
If pending writes are the problem, and not completing, they will have to be cancelled.
I have this 2-side(client and server) program written in c++, which is basically a "chat program".
So one side sends data to the other side which sends data to the other side .
I am using C-Sockets (TCP/SOCK_STREAM).
So my Problem is, that while the server is waiting for data ("recv()") it is unable to send data itself, as the recv queue is infinite, as far as my experience shows.
I have thought of two ways to solve this, but I am not sure if its worth the time. Because there maybe is a simple solution, which I am just too stupid too think of.
Make it a 6-sided connection, meaning I have a "physical Server", where my server is running on in four instances, twice for each client(sending and recieving). so if one server recieves data it stores the data in a file, for the sending server of the other client to read out and.. send it. Works same the other way around.
As this solution sounds rather shitty, I might not go with it.
Using Multithreading. Which is as I have heard pure cancer to use and you shouldn't use it, unless you have to.
So my question is, do I have to? or is there maybe a simple solution?
recv() on a blocking socket is used when you need to wait for incoming data and have nothing to do until data is arrived. If it's not your case you can use non-blocking socket, or select with timeout. select would be simpler, just check if anything arrived on your socket regularly (e.g. in a loop), and do what you want in between.
By the way, it's called "BSD socket", not "C socket", this can help you googling.
For every single tutorials and examples I have seen on the internet for Linux/Unix socket tutorials, the server side code always involves an infinite loop that checks for client connection every single time.
Example:
http://www.thegeekstuff.com/2011/12/c-socket-programming/
http://tldp.org/LDP/LG/issue74/tougher.html#3.2
Is there a more efficient way to structure the server side code so that it does not involve an infinite loop, or code the infinite loop in a way that it will take up less system resource?
the infinite loop in those examples is already efficient. the call to accept() is a blocking call: the function does not return until there is a client connecting to the server. code execution for the thread which called the accept() function is halted, and does not take any processing power.
think of accept() as a call to join() or like a wait on a mutex/lock/semaphore.
of course, there are many other ways to handle incoming connection, but those other ways deal with the blocking nature of accept(). this function is difficult to cancel, so there exists non-blocking alternatives which will allow the server to perform other actions while waiting for an incoming connection. one such alternative is using select(). other alternatives are less portable as they involve low-level operating system calls to signal the connection through a callback function, an event or any other asynchronous mechanism handled by the operating system...
For C++ you could look into boost.asio. You could also look into e.g. asynchronous I/O functions. There is also SIGIO.
Of course, even when using these asynchronous methods, your main program still needs to sit in a loop, or the program will exit.
The infinite loop is there to maintain the server's running state, so when a client connection is accepted, the server won't quit immediately afterwards, instead it'll go back to listening for another client connection.
The listen() call is a blocking one - that is to say, it waits until it receives data. It does this is an extremely efficient way, using zero system resources (until a connection is made, of course) by making use of the operating systems network drivers that trigger an event (or hardware interrupt) that wakes the listening thread up.
Here's a good overview of what techniques are available - The C10K problem.
When you are implementing a server that listens for possibly infinite connections, there is imo no way around some sort of infinite loops. Usually this is not a problem at all, because when your socket is not marked as non-blocking, the call to accept() will block until a new connection arrives. Due to this blocking, no system resources are wasted.
Other libraries that provide like an event-based system are ultimately implemented in the way described above.
In addition to what has already been posted, it's fairly easy to see what is going on with a debugger. You will be able to single-step through until you execute the accept() line, upon which the 'sigle-step' highlight will disappear and the app will run on - the next line is not reached. If you put a breadkpoint on the next line, it will not fire until a client connects.
We need to follow the best practice on writing client -server programing. The best guide I can recommend you at this time is The C10K Problem . There are specific stuff we need to follow in this case. We can go for using select or poll or epoll. Each have there own advantages and disadvantages.
If you are running you code using latest kernel version, then I would recommend to go for epoll. Click to see sample program to understand epoll.
If you are using select, poll, epoll then you will be blocked until you get an event / trigger so that your server will not run in to infinite loop by consuming your system time.
On my personal experience, I feel epoll is the best way to go further as I observed the threshold of my server machine on having 80k ACTIVE connection was very less on comparing it will select and poll. The load average of my server machine was just 3.2 on having 80k active connection :)
On testing with poll, I find my server load average went up to 7.8 on reaching 30k active client connection :(.
I want to know whether its possible for tcp socket to report any broken pipe error immediately. Currently i am catching the sigpipe signal at the client side when server goes down ... but i found that the sigpipe signal is generated
only after 2nd msg is sent from client to server . what could be the possible reason for this?? If the other socket end went down , then the 1st send must return sigpipe .. y isnt that signal generated immediately..??
Is there any possible explanation to this peculiar behaviour?? And any possible way to get around this??
The TCP stack will only throw an error after some number of retransmission attempts. IIRC, the TCP retransmission timer is initialized to some small number of seconds and the number of retransmissions is typically 5-10. The protocol does not support any other means of detecting a peer that has become unreachable during a data exchange, (ie. someone tripped over the server power cable).
I think using SO_KEEPALIVE option may speed up broken link detection.
I want to know whether its possible for tcp socket to report any broken pipe error immediately
The other end of the pipe is across a network. That network could be slow and unreliable. So one end of the pipe can never instantly tell whether its partner still there. The delay could be quite long, so the O/S is also likely to do some bufferring. These considerations make it practically impossible to immediately detect a broken pipe.
And any possible way to get around this
But why would you want to? The pipe could be broken at any time during trans mission, so you have to handle the general case anyway.
I'm having trouble when connecting a socket to an endpoint after being connected to another.
This is the situation:
a) The boost::asio::ip::tcp::socket is connected to a remote host (say pop.remote1.com).
b) The transmission ends, and the socket is closed:
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
socket_.close(error);
Then, when trying to connect to another host (say pop.remote2.com) using the same process that in a), the proccess returns without error, but the socket remains closed.
Note that when using pop.remote2.com as the first connection, the things run Ok, and the same problem arises if try to connect to pop.remote1.com after closing.
In both situations there are not pending processes in the attached io_service.
The questions are:
Is that reconnection admissible?
Is that the supposed correct process?
Thanks in advance.
P.D:
I tried to open the socket before the reconnection, but the result remains the same. That is, the result is the same if after closing the previous connection with.
socket_.shutdown(...);
socket_.close(...);
is used
socket_.open(...);
socket_.async_connect( ... );
or just
socket_.async_connect( ... );
A final thought:
After spent some time on the problem, and do some debug with MS Visual Studio, I think that simply that is not possible, at least in Asio v. 1.45.0; Windows 32 and VC++.
Perhaps the question is that here -at Boost librarys- all people think in and use objects, and if sometime need reconnect, simply delete the apropriate object, and do a new connection... creating a new object!
That was the solution that I do in my application with good results, athought with some extra code.
HTH to some else.
Is that reconnection admissible?
yes
Is that the supposed correct process?
yes and no. If you aren't opening the socket for subsequent connections after you close it for the previous one, you'll need to do that. Ex:
socket_.open();
socket_.async_connect( ... );