TcpListener won't acknowledge connections - c#

So I am writing a simple client-server application. It should send a packet, then wait to receive a packet, than send one etc... The problem is, it recieves the first packet, but when I start the TcpListener in the second iteration, it gives me this error:
No connection could be made because the target machine actively
refused it 127.0.0.1:13
private void listenForConnections()
{
bool prejelPaket = false;
listener = new TcpListener(IPAddress, port);
listener.Start();
while (!packetReceived)
{
try
{
client = listener.AcceptTcpClient();
listener.Stop();
networkStream = client.GetStream();
byte[] message = new byte[1024];
networkStream.Read(message, 0, message.Length);
networkStream.Close();
string strMessage = Encoding.UTF8.GetString(message);
packetReceived= true;
MessageBox.Show("received message: " + strMessage);
client.Close();
}
catch (Exception ee)
{
thListen.Join();
}
}
}
private void sendPacket(object pClient)
{
string message = "test message;
try
{
client = (TcpClient)pClient;
client.Connect(IPAddress, port);
networkStream = client.GetStream();
byte[] strMessage = Encoding.UTF8.GetBytes(message);
networkStream.Write(strMessage, 0, strMessage.Length);
networkStream.Close();
client.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}

Create the client / networkstream once. Store them in a property until you are finished sending and receiving. Then close and dispose. Do not stop / close the connection between each iteration.

Move the
listener.Stop();
outside the while loop.
EDIT: to explain why
The reason why it works the first time but second iteration fails is because after the first client is accepted from client = listener.AcceptTcpClient() the next line of code calls listener.Stop() which stops listening for connections. Any subsequent calls to listener.AcceptTcpClient() will throw an InvalidOperationException. Moving listener.Stop() outside the while loop only stops listening for connections once it exits the loop.
Looking at it again packetReceived is set to true in the first iteration as well, so it's going to exit the while loop after the first client anyway, is this the intended behaviour?

Related

Creating and destroying bluetooth sockets

I am currently trying to write an app for android with Xamarin where I want to create and destroy sockets to the same device, and then redo that process over again. I have written both client and server code. I am having a problem doing that, since the app always crashes on the server side when it tries to read data from the client for a second time.
What I mean is that it is always successful the first time around, but the second time around, it always crashes. We figured out that the problem was on the client though cause once we started keeping the sockets open and reusing them instead of closing them and recreating a new one when needed, it worked as intended and did not crash. Here is the code we ended up using:
[SERVER]
public class BluetoothSocketListener {
private BluetoothScanner _scanner;
private BluetoothServerSocket serverSocket;
private string TAG = "Socket Listener: ";
private Thread listenThread;
public BluetoothSocketListener(BluetoothScanner scanner, UUID uuid) {
_scanner = scanner;
BluetoothServerSocket tmp = null;
try {
tmp = scanner.Adapter.ListenUsingInsecureRfcommWithServiceRecord("AGHApp", uuid);
} catch(Exception e) {
Console.WriteLine(TAG + "Listen failed, exception: " + e);
}
serverSocket = tmp;
listenThread = new Thread(new ThreadStart(StartListening));
listenThread.Start();
}
private void StartListening() {
Console.WriteLine(TAG + "Listening...");
BluetoothSocket socket = null;
while(_scanner.Running){
try {
socket = serverSocket.Accept();
}catch(Exception e) {
Console.WriteLine(TAG + "Accept failed: " + e);
break;
}
if (socket != null) {
lock (this) {
ReadData(socket.InputStream);
socket.Close();
}
}
}
serverSocket.Close();
}
private void ReadData(Stream stream) {
// Check to see if this NetworkStream is readable.
if(stream.CanRead){
byte[] streamData = new byte[1024];
StringBuilder completeMsg = new StringBuilder();
int bytesRead = 0;
// Incoming message may be larger or smaller than the buffer size.
do{
bytesRead = stream.Read(streamData, 0, 1);
completeMsg.AppendFormat("{0}", Encoding.ASCII.GetString(streamData, 0, bytesRead));
}
while(stream.IsDataAvailable());
// Print out the received message to the console.
Console.WriteLine("Message : " + completeMsg);
}
else{
Console.WriteLine("Cannot read from stream");
}
}
}
[CLIENT]
private void SendData(BluetoothDevice device, string msg){
Console.WriteLine(TAG + "Finding socket");
BluetoothSocket socket = null;
if(sockets.ContainsKey(device.Address)) {
socket = sockets[device.Address];
}
else {
socket = device.CreateInsecureRfcommSocketToServiceRecord(_uuid);
socket.Connect();
sockets.Add(socket);
}
Console.WriteLine(TAG + "Socket connected, writing to socket");
byte[] bMsg = Encoding.ASCII.GetBytes(msg);
socket.OutputStream.Write(bMsg, 0, bMsg.Length);
socket.OutputStream.Close();
}
As can be seen, I never actually close the sockets on the client side after I send the message. This is not the problem though since if this is necessary, I can easily do this in some other function.
What I would like is to create and close the socket every time I want to send a message, since I only want to send something every 15 minutes, and the device might have moved and is no longer available. It is also not necessary to keep track of the devices. Fire and forget. This is what we started with and would like to have something similar to this as well:
private void SendData(BluetoothDevice device, string msg){
BluetoothSocket socket = device.CreateInsecureRfcommSocketToServiceRecord(_uuid);
socket.Connect();
Console.WriteLine(TAG + "Socket connected, writing to socket");
byte[] bMsg = Encoding.ASCII.GetBytes(msg);
socket.OutputStream.Write(bMsg, 0, bMsg.Length);
socket.OutputStream.Close();
socket.Close();
Console.WriteLine(TAG + "Socket closed");
}
Something to notice is that the server actually closes the socket after it receives the message, why is that even working? And why can't I close the socket on the client side? Am I missing something integral here?
The exception is a Java.IO exception, where the message reads: bt socket closed, read -1
Would really appreciate some help!

WaitOne(timeout) after exception

I'm currently working on an application that reads dat from a socket.
I was curious, if I have a readDone.WaitOne(600000) with a larger than normal timeout, what happens if the readDone.Set() is never called in my ReadCallBack method due to an exception in the callback method?
Does it wait for the entire duration of the timeout or does it continue excecuting the main thread by handling the exception which is defined outside the ReadcallBack?
EDIT
Here is an example to explain what I mean:
public void SendAndReceive(Message message)
{
try
{
IPAddress ipAddress = IPAddress.Parse(this.host.Address);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, this.host.Port);
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne(host.Timeout);
message.State = MessageState.SENDING;
Send(client, message.Request);
if (sendDone.WaitOne(120000)) // TIMEOUT SET TO 2 MINUTE
{
// Request sent successful. Now attempt to retrieve response.
message.State = MessageState.READING;
Receive(client);
}
else
{
message.State = MessageState.SEND_ERROR;
message.ErrorMessage = "Timeout while sending request to socket.";
}
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
catch (Exception ex)
{
LogManager.ExceptionHandler(ex);
message.ErrorMessage = ex.Message;
message.State = MessageState.EXCEPTION;
}
}
private void Send(Socket client, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
System.IO.MemoryStream dataStream = new System.IO.MemoryStream();
dataStream.WriteByte(1);
dataStream.Write(byteData, 0, byteData.Length);
dataStream.WriteByte(3);
client.BeginSend(dataStream.GetBuffer(), 0, dataStream.GetBuffer().Length, 0, new AsyncCallback(SendCallback), client);
}
private void SendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
client.EndSend(ar);
// Throw exception before .Set can is called
throw new Exception("test");
sendDone.Set();
}
catch (Exception ex)
{
}
}
So to clarify:
sendDone.WaitOne(120000) is set to timeout after 2 minutes, which means, is .Set() is not called in 2 minutes the main thread will continue to execute. My question is, if there is and exception in the SendCallBack before it can call the .Set(), will the sendDone still hold up the main thread for 2minutes, or will it automatically jump to the try catch in SendAndReceive method?
So I tested this, and if an exception is thrown the WaitOne() is cancelled.

Getting Error thrown when TCP connect lost

I have a block of code that "listens" on a TCP port and just sends an string back no matter what is sent. The issue is the client side is just testing to see if the port is active then disconnecting. At which point I get an error thrown.
Cannot access a disposed object
Object name: 'System.Net.Socket.NetworkSystem'
I think the issue is that this code is on a thread and when the connection closes the while loop references a disposed object... how should I prevent the error from firing when the client closes the connection?
//Cretae listener to accept client connections
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
int bytesRcvd; // Received byte count
while (ServiceRunning) // Run forever, accepting and servicing connections
{
try
{
// Receive until client closes connection, indicated by 0 return value
int totalBytesEchoed = 0;
//I THINK THIS IS WHERE THE PROBLEM IS .. THE CLIENTSTREAM.READ???
while (((bytesRcvd = clientStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) && (ServiceRunning))
{
clientStream.Write(responseBytes, 0, responseBytes.Length);
WriteEventToWindowsLog("GSSResponderService", "Received "+System.Text.Encoding.UTF8.GetString(rcvBuffer), System.Diagnostics.EventLogEntryType.Information);
totalBytesEchoed += bytesRcvd;
}
WriteEventToWindowsLog("GSSResponderService", "Responded to " + totalBytesEchoed.ToString() + " bytes.", System.Diagnostics.EventLogEntryType.Information);
// Close the stream and socket. We are done with this client!
clientStream.Close();
tcpClient.Close();
}
catch (Exception e)
{
//THIS IS GETTING TRIGGERED WHEN A CONNECTION IS LOST
WriteEventToWindowsLog("GSSResponderService", "Error:" + e.Message, System.Diagnostics.EventLogEntryType.Error);
clientStream.Close();
tcpClient.Close();
break;
}
}
}
According to MSDN, Read method of NetworkStream class throws IOException when the underlying Socket is closed and ObjectDisposedException when the NetworkStream is closed or there is a failure reading from the network. The same exceptions are thrown by Write method.
Therefore it shoud be enough to catch these 2 exception types and take appropriate action in exception handlers.
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
int bytesRcvd; // Received byte count
while (ServiceRunning) // Run forever, accepting and servicing connections
{
try
{
// Receive until client closes connection, indicated by 0 return value
int totalBytesEchoed = 0;
try
{
while (((bytesRcvd = clientStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) && (ServiceRunning))
{
clientStream.Write(responseBytes, 0, responseBytes.Length);
WriteEventToWindowsLog("GSSResponderService", "Received "+System.Text.Encoding.UTF8.GetString(rcvBuffer), System.Diagnostics.EventLogEntryType.Information);
totalBytesEchoed += bytesRcvd;
}
}
catch(IOException)
{
//HERE GOES CODE TO HANDLE CLIENT DISCONNECTION
}
catch(ObjectDisposedException)
{
//HERE GOES CODE TO HANDLE CLIENT DISCONNECTION
}
WriteEventToWindowsLog("GSSResponderService", "Responded to " + totalBytesEchoed.ToString() + " bytes.", System.Diagnostics.EventLogEntryType.Information);
// Close the stream and socket. We are done with this client!
clientStream.Close();
tcpClient.Close();
}
catch (Exception e)
{
WriteEventToWindowsLog("GSSResponderService", "Error:" + e.Message, System.Diagnostics.EventLogEntryType.Error);
clientStream.Close();
tcpClient.Close();
break;
}
}
}

.NET C# Synchronous Receive doesn't block

Recently I have tackled a strange behaviour of .Net synchronous receive method. I needed to write an application that has nodes which communicate with each other by sending/receiving data. Each server has a receipt loop which is synchronous, after receiving a serialized class it deserializes and processes it. After that it sends asynchronously this serialized class to some chosen nodes (using AsynchSendTo).
The MSDN clearly says that:
"If you are using a connection-oriented Socket, the Receive method
will read as much data as is available, up to the size of the buffer.
If the remote host shuts down the Socket connection with the Shutdown
method, and all available data has been received, the Receive method
will complete immediately and return zero bytes."
In my case it's not true. There are some random cases when the Receive doesn't block and returns 0 bytes (non-deterministic situtation) right away after establishing connection. I'm 100% sure that the sender was sending at lest 1000 bytes. One more funny fact: when putting Sleep(500) before receive everything works just fine. Hereunder is the receiving code:
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
_listener.Bind(_serverEndpoint);
_listener.Listen(Int32.MaxValue);
while (true)
{
Console.WriteLine("Waiting for connection...");
Socket handler = _listener.Accept();
int totalBytes = 0;
int bytesRec;
var bytes = new byte[DATAGRAM_BUFFER];
do
{
//Thread.Sleep(500);
bytesRec = handler.Receive(bytes, totalBytes, handler.Available, SocketFlags.None);
totalBytes += bytesRec;
} while (bytesRec > 0);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (SocketException e)
{
Console.WriteLine(e);
}
Also the sending part:
public void AsynchSendTo(Datagram datagram, IPEndPoint recipient)
{
byte[] byteDatagram = SerializeDatagram(datagram);
try
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(recipient, ConnectCallback, new StateObject(byteDatagram, byteDatagram.Length, socket));
}
catch (SocketException e)
{
Console.WriteLine(e);
}
}
public void ConnectCallback(IAsyncResult result)
{
try
{
var stateObject = (StateObject)result.AsyncState;
var socket = stateObject.Socket;
socket.EndConnect(result);
socket.BeginSend(stateObject.Data, 0, stateObject.Data.Length, 0, new AsyncCallback(SendCallback), socket);
}
catch (Exception ex)
{
Console.WriteLine("catched!" + ex.ToString());
}
}
public void SendCallback(IAsyncResult result)
{
try
{
var client = (Socket)result.AsyncState;
client.EndSend(result);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
class StateObject
{
public Byte[] Data { get; set; }
public int Size;
public Socket Socket;
}
My question: am I using the synchronous receive in a wrong way? Why it doesn't block event though there is data to receive?
You're shooting yourself in the foot.
bytesRec = handler.Receive(bytes, totalBytes, handler.Available, SocketFlags.None);
At the very beginning of the connection, Available will be 0, forcing it to return immediately with 0. Instead, you should specify the number of bytes which are free in your buffer (e.g. bytes.Length-totalBytes), then it will also block.
You may have a concurrency problem here. After you accept a connection, you jump straight into receive. The sender process may not have enough time to reach the call to send and so your handler.Available is 0 and the receive returns.
This is also why the "bug" does not occur when you add the sleep of 500 ms.

Only one usage of each socket address (protocol/network address/port) is normally permitted

I am connecting to TCP/IP port in Asp.Net, basically i have attached a device on this port to which i am reading, it is working fine but on second time when tcp listener tries to start then it generates the above error.
can any body guide me how can i get rid of this error here is my code that i am using to connect to TCP/IP port:
try
{
byte[] ipaddress = new byte[4];
string ip = ConfigurationManager.AppSettings["IP"].ToString();
string[] ips = ip.Split('.');
ipaddress[0] = (byte)Convert.ToInt32(ips[0]);
ipaddress[1] = (byte)Convert.ToInt32(ips[1]);
ipaddress[2] = (byte)Convert.ToInt32(ips[2]);
ipaddress[3] = (byte)Convert.ToInt32(ips[3]);
int portNumber = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
tcpListener = new TcpListener(new IPAddress(ipaddress), portNumber);
tcpListener.Start();
tcpClient = new TcpClient();
tcpClient.NoDelay = true;
try
{
System.Threading.Thread.Sleep(60000);
tcpClient.ReceiveTimeout = 10;
tcpClient = tcpListener.AcceptTcpClient();
}
catch (Exception ex)
{
tcpClient.Close();
tcpListener.Stop();
}
NetworkStream networkStream = tcpClient.GetStream();
byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
try
{
networkStream.ReadTimeout = 2000;
networkStream.Read(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
tcpClient.Close();
tcpListener.Stop();
}
string returndata = Encoding.Default.GetString(bytes);
tcpClient.Close();
tcpListener.Stop();
return returndata.Substring(returndata.IndexOf("0000000036"), 170);
}
catch (Exception ex)
{
if (tcpClient != null)
tcpClient.Close();
tcpListener.Stop();
LogError("Global.cs", "ReceiveData", ex);
ReceiveData();
}
when it comes on this line tcpListener.Start(); for second time then it generates that error
"Only one usage of each socket address (protocol/network address/port) is normally permitted"
If this is in a loop or something, note that if your code doesn't fire any exceptions, then the connection is not closed. It is only closed if there is an exception, which would be caught by the ending catch block
You don't make use of the using keyword or finally blocks to ensure your resources are closed.
If there are exceptions anywhere in your code, the cleanup may not happen. Your multiple catch blocks may get all scenarios, but I can't easily tell by reading the code.
A generally preferred pattern for using resources that need to be cleaned up is:
using (MyResource res = new MyResource())
{
// Do Stuff
}
if MyResource implements IDisposable, or
try
{
MyResource res = new MyResource();
// Do Stuff
} catch (Exception ex)
{
// Whatever needs handing on exception
}
finally
{
res.Close(); // Or whatever call needs to be made to clean up your resource.
}

Categories

Resources