TcpClient C# different behavior from different clients - c#

I have a server which uses TcpClient.AcceptTcpClient() to accept clients.
I also have a client which also uses C# TcpClient like this:
var client = new TcpClient();
client.connect(ip, port);
This is working as it should, but when I try to connect to my server with the tcp_socket_send from kontiki (C-code), it shows unwanted behavior. It looks like when it sends a message, it sends a SYN. Then the server returns SYN-ACK, so that seems fine. When the client then sends the actual message, the server has accepted it as a new TcpClient.
I hope I made my question clear enough, otherwise ask away.
Thanks
EDIT
I've isolated the problem, but I do not have the answer yet.
The problem is that the way kontiki sends data is SYN, then PSH. The way my C# tcpclient sends data is directly PSH. It leaves the SYN. The problem is (It think) that the SYN closes my previous connection somehow.

Related

What are the possible reasons of SocketError.ConnectionReset in TCP Socket

I have a TCP socket based client server system.
Everything works fine but when network is disconnected form client end and reconnect it again i get automatically SocketError.ConnectionReset send form client and regarding this command the socket is closed in the server side. this is also fine.
but when i look in to the client side it shows the socket is still connected with server. (regarding socket is still connected with server [It does not happen every time], sometime it shows disconnected and some times shows connected)
Does it make sense that "server get a SocketError.ConnectionReset from
client end but client is still connected"?
So i want to know what is the possible reasons of SocketError.ConnectionReset and how to handle such type of problem i have mentioned?
Again i say, Everything is working fine in normal environment (e.g if i exit the client it is disconnected the socket same for the server)
Thanks in advance.
EDIT:
Here is the code in the client side. actually it's a timer that tick every 3 second through programs lifetime and check if Socket is connected or not if its disconnected then it tries to reconnect again through a new socket instance
private void timerSocket_Tick(object sender, EventArgs e)
{
try
{
if (sck == null || !sck.Connected)
{
ConnectToServer();
}
}
catch (Exception ex)
{
RPLog.WriteDebugLog("Exception occcured at: "+ System.Reflection.MethodBase.GetCurrentMethod().ToString()+"Message: "+ex.Message);
}
}
In normal situation (without network disconnect/reconnect) if TCP server get a
SocketError.ConnectionReset form any client, in the client side i see
clients socket is disconnected and it tries to reconnect it again
through the code shown. but when situation happen explained earlier,
server gets a SocketError.ConnectionReset but client shows it still
connected. though the TCP server shows the reset command is send form the exact client
side.
There are several causes but the most common is that you have written to a connection that has already been closed but he other end. In other words, an application protocol error. When it happens you have no choice but to close the socket, it is dead. However you can fix the underlying cause.
When discussing a TCP/IP issue like this, you must mention the network details between the client and the server.
When one side says the connection is reset, it simply means that on the wire a RST packet appears. But to know who sends the RST packet and why, you must utilize network packet captures (by using Wireshark and any other similar tools),
https://en.wikipedia.org/wiki/Transmission_Control_Protocol
You won't easily find out the cause at .NET Framework level.
The problem with using Socket.Connected as you are is that it only gives you the connected state as at the last Send or Receive operation. i.e. It will not tell you that the socket has disconnected unless you first try to send some data to it or receive data from it.
From MSDN description of the Socket.Connected property:
Gets a value that indicates whether a Socket is connected to a remote host as of the last Send or Receive operation.
So in your example, if the socket was functioning correctly when you last sent or received any data from it, the timerSocket_Tick() method would never call ConnectToServer(), even if the socket was now not connected.
how to handle such type of problem i have mentioned?
Close the socket and initiate a new connection.

Using WinSocks in C to send data to a c# application on same machine, "target host refusing connectiong(c# part)

I am trying to get data from my interface, written in c, to another application, in c#.
Now, I'm not sure if WinSocks is pure c, but I'm using visual studio and the rest of my interface is 100% pure C.
Here is my "client" written in c#
http://pastebin.com/X9SNcVqn
here is my "server" written in c - loops waiting for a connection, this builds AND RUNS without issues
NOTE: DEFAULT_PORT is 18042, used the same port for client and server side.
I've downloaded wireshark and used the command "tcp.port eq "
http://pastebin.com/FHZyre2V
I also tried going through my windows firewall and NORTON to allow this connection, I couldn't figure out what to do. Most of the tuts I saw where outdated and tabs and options are changed in WINDOWS 7
I chose a port that wasn't being used, I tried using wireshark to see the connections, no luck BUT I scanned the port I used with nmap, before AND after I ran the "server", so it must of atleast have been created
In your C# code you are mixing TcpClient and Socket objects. You don't need both, only the TcpClient. (The Socket code is using the wrong port as well). Once the TcpClient object is connected, call the GetStream method to get a NetworkStream object that you can read and write to to send and receive data to the server process.
See the example code in the documentation, here: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
Your client code contains:
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.1.4"), 18041);
I would not necessarily expect the IP address bound to a network card to necessarily work for localhost-to-localhost connections. I'd recommend changing your client to use 127.0.0.1 or another suitable loopback address.
First,check if the IP adress is correct and if the corresponding port is listeing.
netstat -an | find "port number"
and I think, in the server side code
local.sin_port = (unsigned short)DEFAULT_PORT;
Should be:
local.sin_port = htons((unsigned short)DEFAULT_PORT);

Closing System.Net.Sockets.TcpClient kills the connection for other TCPClients at the same IP Address

Just to be clear, all of the TCPClients I'm referring to here are not instances of my own class, they are all instances of System.Net.Sockets.TcpClient from Mono's implementation of .NET 4.0.
I have a server that is listening for client connections, as servers do. Whenever it gets a new client it creates a new TCPClient to handle the connection on a new thread. I'm keeping track of all the connections and threads with a dictionary. If the client disconnects, it sends a disconnect message to the server, the TCPClient is closed, the dictionary entry is removed and the thread dies a natural death. No fuss, no muss. The server can handle multiple clients with no problem.
However, I'm simulating what happens if the client gets disconnected, doesn't have a chance to send a disconnect message, then reconnects. I'm detecting whether a client has reconnected with a username system (it'll be more secure when I'm done testing). If I just make a new TCPClient and leave the old one running, the system works just fine, but then I have a bunch of useless threads lying around taking up space and doing nothing. Slackers.
So I try to close the TCPClient associated with the old connection. When I do that, the new TCPClient also dies and the client program throws this error:
E/mono (12944): Unhandled Exception: System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: The socket has been shut down
And the server throws this error:
Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
Cannot read from a closed TextReader.
So closing the old TCPClient with a remote endpoint of say: 192.168.1.10:50001
Also breaks the new TCPClient with a remote endpoint of say:192.168.1.10:50002
So the two TCPClient objects have the same remote endpoint IP address, but different remote endpoint ports. But closing the one seems to stop the other from working. I want to be able to close the old TCPClient to do my cleanup, without closing the new TCPClient.
I suspect this is something to do with how TCPClient works with sockets at a low level, but not having any real understanding of that, I'm not in a position to fix it.
I had a similar issue on my socket server. I used a simple List instead of a dictionary to hold all of my current connections. In a continuous while loop that listens for new streams, I have a try / catch and in the catch block it kills the client if it has disconnected.
Something like this on the sever.cs:
public static void CloseClient(SocketClient whichClient)
{
ClientList.Remove(whichClient);
whichClient.Client.Close();
// dispose of the client object
whichClient.Dispose();
whichClient = null;
}
and then a simple dispose method on the client:
public void Dispose()
{
System.GC.SuppressFinalize(this);
}
EDIT: this paste is the OPs resolution which he or she found on their own with help from my code.
So to clarify, the situation is that I have two TCPClient objects TCPClientA and TCPClientB with different remote endpoints ports, but the same IP:
TCPClientA.Client.RemoteEndPoint.ToString();
returns: 192.168.1.10:50001
TCPClientB.Client.RemoteEndPoint.ToString();
returns: 192.168.1.10:50002
TCPClientA needs to be cleaned up because it's no longer useful, so I call
TCPClientA.Close();
But this closes the socket for the client at the other end of TCPClientB, for some reason. However, writing
TCPClientA.Client.Close();
TCPClientA.Close();
Successfully closes TCPClientA without interfering with TCPClientB. So I've fixed the problem, but I don't understand why it works that way.
Looks like you have found a solution but just so you are aware there are many similar pitfalls when writing client/server applications in .net. There is an open source network library (which is fully supported in mono) where these problems have already been solved, networkComms.net. A basic sample is here.
Disclaimer: This is a commercial product and I am the founder.
This is clearly an error in your code. Merely closing one inbound connection cannot possibly close another one. Clearly something else is happening elsewhere in your code.

TcpClient doesn't connect

I am developing an Tcp client in C# and I am using the TcpClient class.
I am not able to connect to the server.
Debugging the application I can see that the call to Connect is successfull but after I do this , I check with netstat the status of the connection on both server and client. The result is that the server the connection is ESTABLISHED, but on the client I cannot see any connection to the server in netstat result.
Reading the TcpClient instance I can see that the property Connected is true so it should be fine but when I try to read from the NetworkStream it hangs.
When I say it hangs I mean that the server is sending data but the readline doesn't get any data at all.
Do you know what could be the issue and some workaround?
Thanks
First, a recommendation: In my experience, TcpClient is best used asynchronously.
In all my usage of TcpClient though, I've never been able to Read a response without first doing a Write with a request. You'll block forever attempting to synchronously await a response to a request you haven't sent.
Expanding on that, sending a request will be done like this:
TcpClient.GetStream().BeginWrite( tcpMessage, ... );
Which will send the request that's in tcpMessage, which will be a bytestream produced from a string like this:
byte[] tcpMessage = httpEncoding.GetBytes( httpMessage );
Which has your request message like this:
httpMessage = "GET / HTTP/1.1\r\n" + ...;
That sends your request, which causes the server to generate a response which you can then collect like this:
TcpClient.GetStream().BeginRead( ... );
And you should finally be able to receive something back!
Even if it's only a "I didn't like your request!" response. 8 D
What you saw is absolutely normal.
Reading the TcpClient instance I can see that the property Connected is true so it should be fine but when I try to read from the NetworkStream it hangs.
When you try to read, the thread will be blocked till the server sends you some data. Otherwise, based on the read method you used, it can be blocked forever.
It depends on the server, but most TCP servers will wait for the client to send a request before it sends a response. It sounds like your thread is waiting for data. Did you set a read timeout?
Make sure you send a request so that the server knows to send you a response.
Normally, you would put your TcpClient into a separate thread and use a read time out to avoid hanging the whole program awaiting a response.
Make sure that you don't use non-blocking (asynchronous) sockets when communicating with a blocking (synchronous) server, you'll only run into problems. Blocking sockets are normal for the web, as most web services use the request/response paradigm.
on client side, what port were you looking for when you did netstat?
Because when client make connections, it would use ephemeral port. Which means it would use any free port # above maximum of well known port number. So, your client maybe using different port # than you are expecting.
And for the networkstream issue, I would have to see the code to determine what went wrong.

How to recover gracefully from a C# udp socket exception

Context: I'm porting a linux perl app to C#, the server listens on a udp port and maintains multiple concurrent dialogs with remote clients via a single udp socket. During testing, I send out high volumes of packets to the udp server, randomly restarting the clients to observe the server registering the new connections. The problem is this: when I kill a udp client, there may still be data on the server destined for that client. When the server tries to send this data, it gets an icmp "no service available" message back and consequently an exception occurs on the socket.
I cannot reuse this socket, when I try to associate a C# async handler with the socket, it complains about the exception, so I have to close and reopen the udp socket on the server port. Is this the only way around this problem?, surely there's some way of "fixing" the udp socket, as technically, UDP sockets shouldn't be aware of the status of a remote socket?
Any help or pointers would be much appreciated. Thanks.
I think you are right in saying: 'the server should not be aware'. If you send an UDP packet to some IP/port which may or may not be open, there is no way of knowing for the server if it reached it's destination.
The only way for the server to know is to have the client send an ACK back. (Also both the client and server must have resend mechanisms in place in cases of lost packages).
So clearly something else is going on in your code (or with the .Net udp implementation)
EDIT:
After Nikolai's remark I checked the docs. And indeed there is a distinction in .Net to about being 'connected' or 'connectionless' when using UDP.
If you use code like this:
UdpClient udpClient = new UdpClient(11000); //sourceport
try{
udpClient.Connect("www.contoso.com", 11000); //'connect' to destmachine and port
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
udpClient.Send(sendBytes, sendBytes.Length);
then apparently you are 'connected'
However if you use code like this:
UdpClient udpClientB = new UdpClient();
udpClientB.Send(sendBytes, sendBytes.Length, "AlternateHostMachineName", 11000);
then you can send to whomever you choose without 'connecting'.
I'm not sure what your code looks like, but it might be worthwhile to check if you are using the correct set of commands which doesn't assume a 'connection'

Categories

Resources