CHANGE:
I have determined the problem has nothing to do with the coding. However the problem stays still, as this appears to be caused by IRC, I'm still in search of the reason.
The server I'm connecting uses two kinds of PING requests:
One is asked upon connecting to server, and it's in format of alpha-numeric values of 8 characters.
Example: PING :EA0E9275.
And another one is after the server sends out MOTD, joins channels, completes "End of /NAMES list". Then after "n delay" server sends me a ping request with current connected host as it's value.
Example: PING :irc.ams.nl.euirc.net
If I send the command "QUIT :Quit Message" before I reply the host PING request, server ignores the QUIT message, and instead, it quits with a server-filled status message similiar to "Client Exited" message.
Example: ERROR :Closing Link: Nick[IP.ADD.RE.SS] (Life is too short...)
However if I send the same command after responding to host PING request, my QUIT gets processed as it should.
Example: ERROR :Closing Link: Nick[IP.ADD.RE.SS] (Quit: Quit Message)
I've checked in the RFC, and found this on QUIT section:
If, for some other reason, a client connection is closed without the client issuing a QUIT command (e.g. client dies and EOF occurs on socket), the server is required to fill in the quit message with some sort of message reflecting the nature of the event which caused it to happen.
Also, if still in need to see the partial code I'm using to accomplish this, you can check it here. However, this is a common issue with mIRC the IRC client.
Basic scheme
Connecting to server...
Connected!
Server waiting NICK/USER info...
Server received NICK/USER info, waiting for alphanumeric PING reply...
Server received alphanumeric PING reply, sending MOTD.
End of MOTD, sending JOIN to join channels...
Joined to channels, NAMES list for channels have been requested.
End of NAMES list.
Receiving active channel(s)/server data.
If sent QUIT command, server will ignore the usual QUIT, and will send "Closing Link" by server default as status quit(Life is too short...).
Server is doing an alive-check, received host PING(irc.ams.nl.euirc.net), server is waiting reply...
Sent server the reply.
If sent QUIT command, server will process QUIT command as user-level, the usual way, and will send "Closing Link" by user-specified message or empty.((QUIT: User Message) or (QUIT: ))
Let's review your code for a bit:
When I made my IRC bot, I explode()ed the string from the server into words (splitting by space), you can then refer to words:
if ($words[0] == "PING") { reply("PONG :" . $words[1]); }
Always PONG immediately after PING, and reply with the same message as the server.
If the second is fulfilled, you should never have that problem of the server waiting a PING, because you'll immediately answer. A client is expected to honor the PING PONG commands from the server, otherwise the server would think of it as offline (yes, even if you send anything else, the server expects PONG).
Related
I am facing an issue with tcp connection..
I have a number of clients connected to the a remote server over tcp .
Now,If due to any issue i am not able to reach my server , after the successful establishment of the tcp connection , i do not receive any error on the client side .
On client end if i do netstat , it shows me that clients are connected the remote server , even though i am not able to ping the server.
So,now i am in the case where the server shows it is not connected to any client and on another end the client shows it is connected the server.
I have tested this for websocket also with node.js , but the same behavior persists over there also .
I have tried to google it around , but no luck .
Is there any standard solution for that ?
This is by design.
If two endpoints have a successful socket (TCP) connection between each other, but aren't sending any data, then the TCP state machines on both endpoints remains in the CONNECTED state.
Imagine if you had a shell connection open in a terminal window on your PC at work to a remote Unix machine across the Internet. You leave work that evening with the terminal window still logged in and at the shell prompt on the remote server.
Overnight, some router in between your PC and the remote computer goes out. Hours later, the router is fixed. You come into work the next day and start typing at the shell prompt. It's like the loss of connectivity never happened. How is this possible? Because neither socket on either endpoint had anything to send during the outage. Given that, there was no way that the TCP state machine was going to detect a connectivity failure - because no traffic was actually occurring. Now if you had tried to type something at the prompt during the outage, then the socket connection would eventually time out within a minute or two, and the terminal session would end.
One workaround is to to enable the SO_KEEPALIVE option on your socket. YMMV with this socket option - as this mode of TCP does not always send keep-alive messages at a rate in which you control.
A more common approach is to just have your socket send data periodically. Some protocols on top of TCP that I've worked with have their own notion of a "ping" message for this very purpose. That is, the client sends a "ping" message over the TCP socket every minute and the server responds back with "pong" or some equivalent. If neither side gets the expected ping/pong message within N minutes, then the connection, regardless of socket error state, is assumed to be dead. This approach of sending periodic messages also helps with NATs that tend to drop TCP connections for very quiet protocols when it doesn't observe traffic over a period of time.
I have an IMAP client (Perl, Mail::IMAPClient) connecting to a MS Exchange server which, upon login, receives the error "1 BAD Command received in Invalid state." This same IMAP client works in a number of other environments with no errors, and certainly not errors immediately at login!
I've had trouble determining the source of the error and at this point I'm inclined to think the customer's Exchange server is misconfigured or there's some firewall or packet manipulation shenanigans afoot.
I was able to take a packet capture that really looks normal other than the error. After the TCP handshake this is the whole IMAP conversation, followed by the TCP hangup.
No. Time Source Destination
4 0.010228000 (server) (client)
Internet Message Access Protocol
Line: * OK The Microsoft Exchange IMAP4 service is ready.\r\n
No. Time Source Destination
5 0.012680000 (client) (server)
Internet Message Access Protocol
Line: 1 LOGIN (username) (password)\r\n
Request Tag: 1
Request Command: LOGIN
Request: LOGIN (username) (password)
No. Time Source Destination
6 0.017559000 (server) (client)
Internet Message Access Protocol
Line: 1 BAD Command received in Invalid state.\r\n
Response Tag: 1
Response Status: BAD
Response: BAD Command received in Invalid state.
Am I right in assuming the problem is on the IMAP server's end?
You need to send a CAPABILITY command first, so that you can check if the server has LOGINDISABLED (which it probably does, hence your error).
I have a client-server (Java) application using persistent TCP connections, but sometimes the Server receives java.io.IOException: Connection reset by peer exception when trying to write on the socket, however I don't see any error in the Client log.
This RST is probably caused by an intermediate proxy/router, but if that's the case, should this be seen on the client as well?
If the RST is sent by the client, it can be seen on it using a packet sniffer such as wireshark. However, it won't show up in any user-level sockets since it's sent by the OS as a response to various erroneous inputs (such as connection attempts to a closed port).
If the RST is sent by the network, then it's pretending to be the client to sever the connection. It can do so in one direction, or in both of them. In that case, the client might not see anything, except for a RST sent by the actual server when the client continues to send data to a connection it perceives as open, while the server sees it as closed.
Try capturing the traffic on both the server and the client, see where the resets are coming from.
I have a C/S program. Client use socket to send a file to server, after send approximate more than 700k data, client(on win7) will receive a socket 10054 error which means Connection reset by peer.
Server worked on CentOS 5.4, client is windows7 virtual machine run in virtual box. client and server communicate via a virtual network interface.
The command port(send log) is normal, but the data port(send file) have the problem.
If it was caused by wrong configuration of socket buffer size or something else?
If anyone can help me check the problem. Thanks.
Every time I call socket send a buffer equals 4096 byte
send(socket, buffer, 4096, 0 )
CentOS socket config.
#sysctl -a
...
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.ipv4.tcp_mem = 196608 262144 393216
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_reordering = 3
net.ipv4.tcp_fack = 1
I'm not quite understand what the socket buffer configuration means, if this will cause the receive incomplete result problem?
It's almost definitely a bug in your code. Most likely, one side thinks the other side has timed out and so closes the connection abnormally. The most common way this happens it that you call a receive function to get data, but you actually already got that data and just didn't realize it. So you're waiting for data that you have already received and thus time out.
For example:
1) Client sends a message.
2) Client sends another message.
3) Server reads both messages but thinks it only got one, sends an acknowledge.
4) Client receives acknowledge, waits for second acknowledge which server will never send.
5) Server waits for second message which it actually already received.
Now the server is waiting for the client and the client is waiting for the server. The server was coded incorrectly and didn't realize that it actually got two messages in one go. TCP does not preserve message boundaries.
If you tell me more about your protocol, I can probably tell you in more detail what went wrong. What constitutes a message? Which side sends when? Are there any acknowledgements? And so on.
But the short version is that each side is probably waiting for the other.
Most likely, the connection reset by peer is a symptom. Your problem occurs, one side times out and aborts the connection. That causes the other side to get a connection reset because the other side aborted the connection.
What is the meaning of the "connection reset by peer" error on a TCP connection? Is it a fatal error or just a notification or related to the network failure?
It's fatal. The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake. This bypasses the normal half-closed state transition. I like this description:
"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur.
This means that a TCP RST was received and the connection is now closed. This occurs when a packet is sent from your end of the connection but the other end does not recognize the connection; it will send back a packet with the RST bit set in order to forcibly close the connection.
This can happen if the other side crashes and then comes back up or if it calls close() on the socket while there is data from you in transit, and is an indication to you that some of the data that you previously sent may not have been received.
It is up to you whether that is an error; if the information you were sending was only for the benefit of the remote client then it may not matter that any final data may have been lost. However you should close the socket and free up any other resources associated with the connection.
one of the reasons for seeing this error and having trouble connecting to the server is that you enabled the firewall in the UNIX machine and forgot to add a rule to accept ssh connection. search in your WPS provider and you will find a way to connect to you machine and add this rules:
ufw allow ssh && ufw allow 22