I'm using the following TCP Sockets Server/Client example: http://www.codeguru.com/Csharp/Csharp/cs_network/sockets/article.php/c8781/
I'm also using the following CryptoStream example:
http://www.obviex.com/samples/Encryption.aspx
Problem: Both Server and Clients communicate perfectly until I Stop the Server socket, wait a minute or so, then start the Server socket. Sometimes but not always I recieve a base64 error in the Encryption.aspx on line 'Convert.FromBase64String(cipherText);'...
I know there is incorrect / corrupted data in the buffer probably left-over from stopping the socket. Then the new data comes in and the error occurs.
Q. Will clearing the 'class SocketPacket; solve this issue?
Q. How do I clear the 'class SocketPacketsocketBuffer'?
Other suggestions are greatly appreciated..
One of the things you may find is happening is that one of the sockets is not being closed down properly. The thing with sockets is that you need to make sure they get correctly closed or you set the server socket to reuse the address.
Try tcpview from sysinternals to view the status of sockets. You can also use netstat to view the status of the sockets.
Related
I would like to connect to a specific barcode reader at my work but currently I'm facing some problems to understand how TCP stream reading works with C#.
I've looked for many code samples on stackoverflow and as I can see, people oftenly open a connection, send a command and then ask for the reply.
The point is, the barcode reader just accept a TCP connection and then send the data with my data.
I would like find the most efficient way to use TcpClient or NetworkStream to read in a continuous way the data. I mean, I would like to listen for the data when it's incoming but also process many other things at the same time I'm listening.
I was wonderning if simple TCP libraries exists like a one with a Connect function, and an event firing when you receive data (with a delimiter or with a length).
Thanks
I finally found a simple TCP library called SimpleTCP. I'm able to connect to my network barcode reader with the following line of code: g_Client.Connect(ip, port);
Then there is an event available called DataReceived (g_Client.DataReceived += l_Client_DataReceived;) which allow me to do exactly what I want.
This library also gives access to the TcpClient it's using and I'm currently searching for the possibility to see the special characters such as < STX >(currently returning me a special char in ASCII) but I will have to do another thread for this I think.
TCP doesn't sound right, but if it is it might be acting as a http server.If it is then you'd use a HttpClient. If it is just TCP, you would do something like:Async Client Socket
I am trying to create tcp connection.
I am sending tcp SYN and getting SYN-ACK.
Afterwards, I am sending ACK message.
However, before my last ACK is sending I am getting RST reset packet. I can see that using wireshark sniffer.
I am writing my code in C# , an using pcap .NET library, over Win7.
How can I fix the problem and what makes it happen?
Your problem is, that your OS receives a SYN/ACK that it cannot associate on a source port and thus the OS TCP/IP stack sends a RST.
What do you exactly want to do? You could suppress the RST with a local firewall.
I'm writing a service that needs to maintain a long running SSL connection to a remote server. I need this server to be self-healing, that is if it's disconnected for any reason then the next time it's written to it will reconnect. I've tried this:
bool isConnected = client.Connected && client.Client.Poll(0, SelectMode.SelectWrite) && stream.CanWrite;
if (!isConnected )
{
this.connected = false;
GetConnection();
}
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
But I find it doesn't act as I would expect it. If I simulate a network outage by disabling my wifi, I'm still able to write to the stream with stream.Write() for approximately 20 seconds. Then next time I try to write to it, none of client.Connected, client.Client.Poll(), or stream.CanWrite() return false, but when I go to write to the stream I get a socket exception. Finally, if I try to recreate the connection, I get this exception: An existing connection was forcibly closed by the remote host.
I would appreciate any help create a long running SslStream that can withstand network failure. Thanks!
From a 10.000 feet point of view:
The reason you can still write to the stream after shutting down your wifi is because there is a network buffer that is holding the data for transmission, stream.Write/stream.Flush success means the network interface (TCP/IP stack) has accepted the data and has been buffered for transmission, not that the data has reach its target.
It takes time to the TCP/IP Stack to notice a full media disconnection, (connection lost/reset) because even if there is no physical link TCP/IP will see this as a temporary issue in the network and will keep retrying for a while (the network could be dropping packets at some point and the stack will keep retrying)
If you think about this in the reverse way, you won't like all your programs to fail if there is a network hiccup (this happen too often on internet), so TCP/IP takes its time to notify to the app layer that the connection has become invalid (after retry several times and wait a reasonable amount of time)
You can always reconnect to the server when the SslStream fails and continue sending data, although you will find is not as easy as this because there are several scenarios where you send and data is not received by server and others where server receive the data and you do not receive any ACK from server at all... So depending on your needs, self-healing alone could be not enough.
Self-Healing is simple to implement, data consistency and reliability is harder and usually requires the server to be ready to support some kind of reliable messaging mechanism to ensure all data has been sent and received.
The underlying protocol for SSL is TCP. TCP will usually only send data if the application wants it to deliver data, or if it needs to reply to data received from the other side by sending an ACK. This means, that a broken connection like a lost link will not be noticed until you are trying to send any data. But you will not notice immediatly, because:
A write to the socket will only deliver the data to the OS kernel and return success if this delivery was successful.
The kernel will then try to deliver the data to the peer and will wait for the ACK from the client.
If it does not get any ACK it will retry again to deliver the data and only after some unsuccessful retries the kernel will declare the connection broken.
Only after the connection is marked broken by the kernel the next write or read will return the error from kernel to user space, like with returning EPIPE when doing a write.
This means, if you want to know up-front if the connection is still alive you have to make sure that you get a regular data exchange on the connection. At the TCP level you might set TCP_KEEPALIVE, but this might use an interval of some hours between exchanges packets. At the SSL layer you might try to use the infamous heartbeat extension, but most peers will not understand it. The last choice is to implement some kind of heartbeat in your own application.
As for the self healing: When reconnecting you get a new TCP connection and you also need to do a full SSL handshake, because the last SSL connection was not cleanly closed and thus cannot be resumed. The server has no idea that this new connection is just a continuation of the old one so you have to implement some kind of meta-connection spanning multiple TCP connections inside your application layer on both client and server. Inside this meta-connection you need to have your own data tracking to detect, which data are really accepted from the peer and which were only send but never explicitly accepted because the connection broke. Sound like a kind of TCP on top of TCP.
Edit: Yes I know that UDP doesn't technically connect, but you can still use it to set the default target for Send(), which is what I'm doing here.
Basically I have this problem that between calls to MySocket.Send(), MySocket is becoming disconnected i.e. the Connected variable becomes false (I know that Connected isn't necessarily up-to-date, but no data isn't being sent so I know that it's telling the truth).
The strange thing is that the RemoteEndPoint variable is still set correctly, but when I call Send(), no data is recieved by the other computer. However if I call Connect() again, the socket does connect, and I'm able to send data (at least until the next time the user does something that causes another call to Send() )
Can anyone tell me why a socket would spontaneously disconnect?
The line where I connect it is:
opep = new IPEndPoint(Opponent.Address, 1000);
Listener.Connect(opep);
I don't see anything here that could be garbage collected for example to cause this issue.
Thanks!
UDP doesn't set up a connection. You should check out the following link for more info
Difference between TCP and UDP?
I've a plugin which always listening to the port 6002, and i have an ASP.net application which sending messages to the same port and receiving the reply from the plugin on the same port,
Sending is working fine, and the plugin sends a reply on the same port but i don't know how to catch this reply, when i try to listen to the same port using Tcplistener the start method throws this exception : Only one usage of each socket address (protocol/network address/port) is normally permitted,
is there any way to catch the received message
Thanks
It sounds like you are wrongly assuming that the Socket which you get from TcpListener.AcceptSocket can only be used in one direction.
Sockets can actually be bidirectional. You can use Send to send something, and Receive to listen for get the replies. Open one socket, and then use it for both sending and receiving.
In short, no.
Once a port is opened an exception will be thrown if further attempts are made to utilise that same port from a different source - as you are experiencing right now. There isn't a way to get around this.
I've solved this problem using this way ,, I know it's old method but it's working !! :
'/*Variables Initialization*/
dim objSocket, strServicePort, strIpAddr, strResult, strMsgTo, strMsgResponse
strServicePort = "6002"
strIpAddr = "127.0.0.1"
'/* Create a TCP/IP socket. */
objSocket = Server.CreateObject("Intrafoundation.TCPClient.3")
objSocket.ClearLog()
'/* Establish socket connection. */
objSocket.Open (strIpAddr,strServicePort)
objSocket.Timeout=60.0
strMsgTo ="---- Message here ----"
'/* Send request message to plugin */
objSocket.SendRN(strMsgTo)
'/* receive XML Request Message from plugin */
strMsgResponse = objSocket.Recv()
strMsgResponse = Replace(strMsgResponse, vbLf, "")
objSocket.Close()
If you want to inspect traffic you can use winpcap.
edit: I don't think you are asking the right question. In this case the plugin is the server (listening on port 6002) and your ASP.net app is the client listening on some arbitrary port. You only need to bind to a different port in your ASP.net app if it also needs to run as a server with the plugin acting s the client. In this case you should pick a different port even though there are, in fact, ways to make it work when they are both bound to the same port.
In your case though you should just read back responses from the connection you established from the client.