HttpWebRequest/StreamWriter fails every 50th request - sockets

I'm having a problem with a .NET client connecting to an apache server for XML requests. Exactly every 50th time XML is transferred the response seems to be lost.
Looking at a WireShark trace on the client I can see that every 50th time the apache server sends an encrypted alert followed by a FIN, ACK. The client responds with a RST which closes the socket, but then the client continues to try to use the socket, it sends SYN packets without any response. When this happens the response doesn't get back to the application layer on the client.
After the client times out and reconnects (renegotiates encryption) it works another 49 times and then fails again.
Just to add this same .NET client is in use on many other client machines without a problem.
I can't find anyone else having this issue. Any ideas how to resolve this?

Related

What are the problems in 3-way Message passing Reliable IPC protocol?

Here, at the end of this page. last paragraph ,
They mentioned some problems that occurs in This protocol.
i am unable to understand what are these problems. ?
for example. He told. "If a request processing long time"
I am unable to understand this statement. Where is the request which processing taking long time, on client ? or on server ?
Or i am unable to understand where is the Clock(time) ? is it on Client side or Server Side? because here mentioned in the end of 2 point. "if the reply is not received within the time period , the kernel of the client machine re-transmits the request message."
Consider this:
The client sends a message. If it doesn't get a reply from the server within - say - 1 minute it will transmit the message again.
When the server receives a message, it only sends a reply after having generated a full response to the message that the client sent.
No suppose you, as client, send a message to the server. The server receives your message, and starts processing it. At this time, you, the client, have no idea of whether the server got the message or not. Assume you send a complicated task to the server, which takes it 1 minute and 5 seconds to complete. After 1 minute (ignoring transmission times), the server is still busy doing your work, but you as the client don't know of any of this and send your message again.
Now, depending on the actual protocol implementation, there are a few potential issues:
It's possible that by sending the message again, you increase some sequence count and are therefore unable to receive the reply to the original message afterwards.
It's possible that the server isn't able to determine whether a message that arrives is the first message or a message that had to be send again. So it could be doing work that it already did, leading either to needless processing or in the worst case to (business) logic errors.
Additionally, by sending both the message and the reply possibly needless more than once, you increase the amount of total data transmitted, without gaining anything from it.
To "solve" this, you could increase the waiting time before the client sends its message again. This will "fix" the issue with long running tasks on the server, but will also hurt in case the message actually got lost on the way, because you're waiting longer to even send a new message.
The "real" solution here is to have the server acknowledge as soon as it receives a message from the client, just as saying "i got your message, i'll send the reply soon!" before even starting to actually process the message.

UDP response received after timeout

We have an UDP client that communicates against a server.
The server gives a single response on each request.
The client sends a request, and waits 5 seconds for the response.
If the server's response was not received by 5 seconds - the client assumes that the packet was lost in the network (this is UDP...), writes a report to a log, and sends the next request.
But, sometimes we have any delay in the network, and the server's response comes after 5 seconds.
Let's describe the scenario:
The client sent a packet named "X".
The timeout of 5 seconds expired, and the client reports that "X" is a lost packet.
The client sent another packet named "Y".
The server's response on "X" comes now to the client.
The client sees that the response is not compatible to the request, and report it to the log.
The client sent another packet named "Z".
The server's response on "Y" comes now to the client.
The client sees that the response is not compatible to the request, and report it to the log.
And this is an infinity loop!
What can we do?
Many UDP-based protocols include an identifier to indicate which request a given response belongs to. The client chooses the identifier and sends it to the server as part of the request, and then the server echoes it back in the response. This allows the client to match responses to requests, especially in situations like the one you describe. If the client received the response to X after having moved on, it would be able to simply ignore that response.

Using FIX protocol to connect to the broker

I am currently trying to build a program using FIX protocol to communicate with a broker (currenex). I sent my (self-generated) logon message to the server and got something back.
This is what I sent
8=FIX.4.49=8835=A49=xxxxxxxx56=CNX34=152=20140718-11:40:18.24498=0108=30141=Y554=xxxxxx10=128
(the SenderCompID and the password were replaced)
and I got
8=FIX.4.49=7635=A34=149=CNX52=20140718-11:40:33.22456=xxxxxxxx141=Y98=0108=3010=1458=FIX.4.49=7035=h34=249=CNX52=20140718-11:40:33.22656=xxxxxxxx336=0340=210=128
back from the server.
I think I built the logon message correct (or did I?). But when I sent a second request MarketDataRequest
8=FIX.4.49=13735=V49=xxxxxxxx56=CNX34=252=20140718-11:42:53.504262=363263=1264=0265=1266=N267=2269=1269=0146=155=GBP/USD554=xxxx10=013
I had no response at all. I asked the broker and they said the connection dropped right away every time after I logged in.
I thought it was some connection problem and I tried using RESTClient (Postman) to send the message but the result was the same.
Could any one take a look at my messages and point out if there is something stupid please?
All I need is the real-time exchange rate so a simple FIX message example will be very helpful. Thanks a lot!
Regards,
Bo
Your logon response message says that your trading session is open (340=2) so it's not broker-side problem. I think your program disconnects TCP/IP connection from server after login message. FIX protocol insists that TCP/IP connection must be kept alive during the whole FIX session - otherwise the session will be closed. So you need rewrite your program to keep connection alive and just send there yor requests and listen for responses. Don't close the connection.
Try using Minifix tool which will maintain the heartbeats and the session connection.
Ideally for a 35=V request you should get
35=W = Market Data-Snapshot/Full Refresh
35=X = Market Data-Incremental Refresh
35=Y = Market Data Request Reject
you get a 35=3 (reject) or 35=4 (or a seq reset) in response to a 35=A request.

Discard response on EAGAIN

I have a client application that repeatedly sends commands over a socket connection to a server and receives corresponding responses. This socket connection has a send/recv timeout set.
If the server is slow to respond for some reason, the client receives EAGAIN. On a timeout, I want the client to ignore that response and proceed with sending the next request.
However, currently when I ignore EAGAIN and send the next request, I receive the response from a previous request.
What is the best way to ignore/discard the response on an EAGAIN?
You can't. You have to read it. There is no mechanism to ignore bytes in a TCP byte stream.
EAGAIN may indicate a timeout elapsed (you also need to handle EWOULDBLOCK as well). If you are using TCP, you must read pending data before you can read any subsequent data. If you get an EAGAIN on a read, you have to perform the same read again, using the same parameters. Just because the server is slow to respond (or the network is slow to deliver the response) does not mean the response will not arrive at all, unless the connection is closed/lost.
If you really want to be able to receive responses out of order, you need to design your communication protocol to support that in the first place. Give each request a unique ID that is echoed in its response. Send the request but do not wait for the response to arrive. That will allow the client to have multiple requests in flight at a time, and allow the server to send back responses in any order. The client will have to read each response as it arrives (which means you have to do the reading asynchronously, typically using a separate thread or some other parallel signaling mechanism) and match up each response's ID to its original request so you know how to then process it.

Reason for not properly closed socket?

Here is what I am trying to do:
The server sends message to connected clients when new messages are available. The client, on the other hand, when connected, tries to send a message to the server using send() and then receive message using recv(), right after that, the client calls close() to close the connection.
Sometimes, after the client finishes, the server tries to receive message from client will result in a 104 - "connection reset by peer" error. When this happens, Wireshark reveals that the last two segments sent by the client is:
1. an ACK acknowledging the receipt of the message sent by the server
2. a RST/ACK
No FIN is sent by the client.
Why is this happening and how can I close the socket "properly" at the client?
This will occur if you call close() in the client with data still in the receive queue. The client will send RST instead of FIN, as an indication that not all data was successfully delivered to the application. If the connection was only for the benefit of the client then probably the server does not care; since no further communication is possible on that socket the server should simply close it.
This can be avoided by shutting down the connection as follows (where A is the side initiating the shutdown):
When A is finished sending all data, it calls shutdown(sock, SHUT_WR) and continues to read from socket.
When B sees EOF (e.g. recv() returns 0), it knows A is initiating a shutdown. B sends any final responses or other final data as applicable, calls shutdown(sock, SHUT_WR), and then close(sock).
When A sees EOF, if it has already shut down writes it just calls close(sock).
Note that ECONNRESET is still possible, if for example the other process is killed, so it must still be handled. In this case there is no point in sending any final response since the other side will not receive it, so the socket should just be closed in that case.