C# check multiple client connections - c#

I am currently developing a one-to-many relationship between one server and many clients.
Everytime a client connects I append to the client list: clientList.Add(client);
I wrote the following code to check the "pulse" of the client connection as to see if the client is still connected and currently updating the toolStripStatusLabel1
This seems to work well when checking one connection and in addition, I added the exception cleanup() when trying to send data so that it should check at all scenarios(Feel free to give your opinion).
My question now is, how do I check the connection from multiple clients?
Please find below the reference code:
private void StartListen()
{
//Creating a TCP Connection and listening to the port
tcpListener = new TcpListener(System.Net.IPAddress.Any, 6666);
tcpListener.Start();
toolStripStatusLabel1.Text = "Listening on port 6666 ...";
int counter = 0;
appStatus = 0;
while (true)
{
try
{
client = tcpListener.AcceptTcpClient();
counter++;
clientList.Add(client);
IPEndPoint ipend = (IPEndPoint)client.Client.RemoteEndPoint;
//Updating status of connection
toolStripStatusLabel1.Text = "Connected from " + IPAddress.Parse(ipend.Address.ToString());
appStatus = 1;
th_outPutStream = new Thread(delegate () { outPutStream(client); });
th_outPutStream.Start();
th_inPutStream = new Thread(delegate () { inPutStream(client); });
th_inPutStream.Start();
th_checkConnection = new Thread(checkConnection);
th_checkConnection.Start();
}
catch (Exception err)
{
Cleanup();
}
}
}
private void checkConnection()
{
bool status = true;
while (status == true)
{
status = IsConnected();
if (status == true)
{
System.Threading.Thread.Sleep(3000); //Wait 3 seconds then try again
}
else
{
Cleanup();
}
}
}
private bool IsConnected()
{
try
{
return !(client.Client.Poll(1, SelectMode.SelectRead) && client.Client.Available == 0);
}
catch (SocketException) { Cleanup(); return false; }
}

I did this by simply creating a forloop for each client in my client list:
private void checkConnection()
{
bool status = true;
while (true)
{
for (int i = 0; i < clientList.Count; i++)
{
Debug.WriteLine(clientList.Count);
status = IsConnected(i);
if (status == true)
{
}
else
{
Cleanup(i);
}
}
System.Threading.Thread.Sleep(3000); //Wait 3 seconds then try again
}
}
private bool IsConnected(int i)
{
try
{
return !(clientList[i].Client.Poll(1, SelectMode.SelectRead) && clientList[i].Client.Available == 0);
}
catch (SocketException) { Cleanup_dep(); return false; }
}

Related

TCP connections stuck with CLOSE_WAIT state

I need your help guys in order to fix issue with non closing TCP connection.
Basically it works fine but after a few minutes it stucks with connection in CLOSE_WAIT state.
The logic of the code:
The code accepts first packet and parse it and after that it sends the CRC back to the client. If the CRC valid then client sends the main packet to the server and repeat it. Once if there are no packets then client close connection but sometimes it does not. In this case server (code below) close connection after 1 minute of the communications.
I assume it should correspond to https://www.googlecloudcommunity.com/gc/Cloud-Product-Articles/TCP-states-explained/ta-p/78462 as well
Here is C# code
void TCPListenerServer(object obj) {
CancellationToken token = (CancellationToken) obj;
if (token.IsCancellationRequested) {
isDisposed = true;
if (listener != null) {
listener.Stop();
}
return;
} else {
try {
isDisposed = false;
try {
var validIP = IPAddress.Parse(Properties.Settings.Default.ServerIP);
listener = new TcpListener(validIP, Properties.Settings.Default.ServerPort);
listener.Start();
while (isDisposed == false || token.IsCancellationRequested == false) {
if (token.IsCancellationRequested || isDisposed) {
break;
} else {
if (!listener.Pending()) {
Thread.Sleep(50);
continue;
}
listener.Server.ReceiveTimeout = 10000;
listener.Server.LingerState = new LingerOption(true, 0);
var client = listener.AcceptTcpClient();
var arrThread = new ThreadParams() {
Client = client, Token = m_Cts.Token
};
var t = new Thread(ProcessClientRequests) {
IsBackground = true,
Name = "ClientConnectionThread",
};
clientThreads.Add(t);
t.Start((object) arrThread);
}
}
} catch (SocketException ex) {
if (ex.SocketErrorCode == SocketError.Interrupted) {}
} catch (Exception ex) {} finally {
if (listener != null) {
listener.Server.Close();
listener.Stop();
}
}
} catch (Exception ex) {
}
}
}
private void ProcessClientRequests(object argument) {
TcpClient client = ((ThreadParams) argument).Client;
CancellationToken token = ((ThreadParams) argument).Token;
client.SendTimeout = 10000;
client.ReceiveTimeout = 10000;
client.LingerState = new LingerOption(true, 0);
var bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
var isFirstPacket = true;
var startTime = DateTime.Now;
DateTime endTime = DateTime.Now;
try {
using(NetworkStream stream = client.GetStream()) {
do {
Thread.Sleep(20);
} while (!stream.DataAvailable);
while ((client != null && client.Connected) && stream != null && stream.CanRead && (endTime - startTime).TotalMinutes < 1) {
if (client == null) {
break;
}
do {
if (token.IsCancellationRequested) {
return;
}
if (client == null) {
break;
}
endTime = DateTime.Now;
int streamReadBytes = 0;
streamReadBytes = stream.Read(buffer, 0, buffer.Length);
if (streamReadBytes == 0) {
if (client != null) {
client.Close();
}
break;
}
if (buffer[0] == (byte) GalileoskyPacketHeaderEnums.FirstPacket || buffer[0] == (byte) GalileoskyPacketHeaderEnums.MainPacket) {
var parserGalileosky = new Galileosky();
var packetResult = parserGalileosky.ParsePacket(buffer, isFirstPacket);
if (packetResult == null) {
if (client != null) {
client.Close();
client = null;
}
break;
}
if (packetResult.Errors.Any()) {
if (client != null) {
client.Close();
client = null;
}
} else {
var imei = packetResult.Packet.IMEI;
if (isFirstPacket) {
isFirstPacket = false;
if (stream.CanWrite == true && packetResult.Packet.IsCrc) {
var answerPacket = packetResult.Packet.GetConfirmPacket();
stream.Write(answerPacket.Ready);
} else {
if (client != null) {
client.Close();
client = null;
}
}
} else // The Main Packet processing
{
// ... Some code to send the main packet to the app queue
if (stream.CanWrite == true && !packetResult.Errors.Any() && packetResult.Packet.IsCrc) {
var answerPacket = packetResult.Packet.GetConfirmPacket();
stream.Write(answerPacket.Ready);
}
if (packetResult.Packet.IsExtraData == false) {
if (client != null) {
client.Close();
client = null;
break;
}
}
}
}
} else {
if (client != null) {
client.Close();
client = null;
}
}
if ((endTime - startTime).TotalMinutes > 1) {
if (client != null) {
client.Close();
client = null;
break;
}
}
}
while ((client != null && client.Connected) && stream != null && stream.CanRead && stream.DataAvailable && (endTime - startTime).TotalMinutes < 1);
}
}
if (client != null) {
client.Close();
client = null;
}
} catch (Exception ex) {} finally {
if (client != null) {
client.Close();
client = null;
}
}
}
Even if your code is correct, you can hit the "2 generals" problem. There is no perfect algorithm for two parties to agree that a connection is closed, when there may be packet loss.
Gracefully closing a TCP stream requires both parties to shutdown sending, read data up to EOF, then close. I believe that you'll see a socket in CLOSE_WAIT, if one party has shutdown the connection, but the other has not. It looks like you have set your sockets to linger. In which case the operating system will take over the lifetime of the socket for you.
If your socket is not set to linger, then closing the socket early will cause data that you think you've sent to be lost.
I should also point out that your code is drastically over complicated, with error handling repeated everywhere. It looks like it was probably written before C# introduced async / await.
It also seems that you are assuming that one read operation equates to one data packet. But this is a TCP stream. The OS is allowed to fragment and recombine data that was written from one end, into any number of data reads at the other.
I'd suggest you search the internet for an example that uses .AcceptTcpClientAsync, .ReadAsync, .WriteAsync etc.
Finally I could'n find a way to solve problem to close connection within my code.
But I added a timer that close connection and it works just awesome!
private void ProcessClientRequests(object argument)
// ... The same code of my quetion
Timer timerCloseConn = new(new TimerCallback((e) =>
{
if (stream != null)
{
stream.Close();
stream.Dispose();
}
if (client != null)
{
if (client.Client.Connected)
{
client.Client.Shutdown(SocketShutdown.Both);
}
client.Close();
client.Dispose();
client = null;
}
Logger.Info("The connection has been closed by
timer's rule!");
}), null, 60000, Timeout.Infinite);
// ... The same code of my quetion
}

Multithreading: Confusion between the publisher thread and the subscriber thread

I have created a Windows forms application which able to publish OPC tags into an MQTT broker, Now I'm trying to do the reverse, write MQTT tags into an OPC server. when I have started both the agent (the publisher) and the transfer (the subscriber) the two threads do the same work which is publishing I don't know what is the problem.
The start method is below :
public byte Start()
{
try
{
byte connectResult;
if (IsLWT == false)
{
connectResult = this._MqttClient.Connect(ClientID, Username, Password, IsCleanSession, KeepAlivePeriode);
}
else
{
connectResult = this._MqttClient.Connect(ClientID, Username, Password, willRetain, willQos, true, willTopic, willMessage, IsCleanSession, KeepAlivePeriode);
}
// 0 means that the connection suceeded
if (connectResult == 0)
{
this.Rate = GetRateFromOPCGroups();
this._publisherThread = new Thread(() => Publish());
this._publisherThread.IsBackground = true;
this._publisherThread.Start();
IsStarted = true;
}
if (connectResult == 0)
{
//this.Rate = GetRateFromOPCGroups();
this._SubscriberThread = new Thread(() => Subscribe(topics));
this._SubscriberThread.IsBackground = true;
this._SubscriberThread.Start();
IsStarted = true;
}
return connectResult;
}
catch (IntegrationObjects.Networking.M2Mqtt.Exceptions.MqttClientException ex)
{
MQTTServiceLogger.TraceLog(MessageType.Error, MQTTServiceMessages.startAgentFailed(this.Name,ex.Message));
return 11;
}
catch (IntegrationObjects.Networking.M2Mqtt.Exceptions.MqttCommunicationException ex)
{
MQTTServiceLogger.TraceLog(MessageType.Error, MQTTServiceMessages.startAgentFailed(this.Name, ex.Message));
return 11;
}
catch (Exception ex)
{
MQTTServiceLogger.TraceLog(MessageType.Error, MQTTServiceMessages.startAgentFailed(this.Name, ex.Message));
return 11;
}
}
1.This is the publish code:
private void Publish()
{
while (true)
{
if (IsStarted)
{
try
{
if (_MqttClient.IsConnected)
{
isConnected = true;
if (this.OPCItems.Count != 0)
{
JsonMQTTMessage JsonMessage = new JsonMQTTMessage();
JsonMessage.Timestamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
JsonMessage.ListofValues = new List<UpdatedOPCItem>();
lock (lockOPCItems)
{
foreach (OPCItem Item in OPCItems.ToList())
{
if (Item != null)
{
UpdatedOPCItem upItem = new UpdatedOPCItem();
upItem.ID = Item.ItemID;
upItem.value = Item.ItemCurrentValue;
upItem.quality = Item.ItemQuality;
upItem.timestamp = Item.ItemTimeStamp.ToString("yyyy/MM/dd HH:mm:ss.fff");
upItem.DataType = Item.ItemDataType;
JsonMessage.ListofValues.Add(upItem);
}
}
}
var messageTopublish = Newtonsoft.Json.JsonConvert.SerializeObject(JsonMessage);
ushort res = _MqttClient.Publish(Topic, Encoding.UTF8.GetBytes(messageTopublish), Qos, Retain);
ResetValues();
Thread.Sleep(Rate);
This is the Subscribe code:
public void Subscribe(List topics)
{
while (true)
{
if (IsStarted)
{
try
{
if (_MqttClient.IsConnected)
{
isConnected = true;
foreach (string topic in topics)
{
ushort msggId = _MqttClient.Subscribe(new string[] { $"{ topic }" },
new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
}
Thread.Sleep(Rate);
}
else

Check connection to local Server:Port with waiting time

I'm trying to make a function to test the connection to server:port, it will try connecting to that server:port each 100ms and return TRUE if connection is success either return FALSE until the time limit is reached.
I have a function as bellow:
private static bool _TryPing(string strIpAddress, int intPort, int nTimeoutMsec)
{
Socket socket = null;
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);
IAsyncResult result = socket.BeginConnect(strIpAddress, intPort, null, null);
bool success = result.AsyncWaitHandle.WaitOne(nTimeoutMsec, true);
return socket.Connected;
}
catch
{
return false;
}
finally
{
if (null != socket)
socket.Close();
}
}
The problem is i'm using another software to make that local Server:Port, and it will take random 10-20sec to complete setting a new port. But the function above will check at the app starts so it will return false immediately without waiting time because the port is not opened yet.
_TryPing("127.0.0.1", 1080, 20000) //Return FALSE
Could anyone help me to fix this code. Thanks
If the port is not open then the connect will fail immediately. If you want to wait for a period of time to see if the port ever opens, you need to retry the connect in a loop until it is successful or the timeout has elapsed, eg:
private static bool hasElapsed(ref Stopwatch sw, int total)
{
return (sw.ElapsedMilliseconds > (long) total);
}
private static bool hasElapsed(ref Stopwatch sw, int total, out int remaining)
{
remaining = (int) (((long) total) - sw.ElapsedMilliseconds);
return (remaining < 0);
}
private static bool _TryPing(string strIpAddress, int intPort, int nTimeoutMsec)
{
Stopwatch sw = Stopwatch.StartNew();
do
{
try
{
using (TcpClient tcp = new TcpClient())
{
tcp.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
IAsyncResult ar = tcp.BeginConnect(strIpAddress, intPort, null, null);
WaitHandle wh = ar.AsyncWaitHandle;
try
{
int remaining;
if (!hasElapsed(ref sw, nTimeoutMsec, out remaining))
{
if (wh.WaitOne(remaining))
{
tcp.EndConnect(ar);
return true;
}
}
tcp.Close();
}
finally
{
wh.Close();
}
}
}
catch
{
}
}
while (!hasElapsed(sw, nTimeoutMsec));
return false;
}
Try this one, i don't know why but i need to devide WaitTime by 3 to make this function run properly...
private static bool TryConnect(string IP, int Port, int WaitTime)
{
int RunEvery = 500;
for (int i = 0; i <= WaitTime/3; i += RunEvery)
{
TcpClient client = new TcpClient();
try
{
client.Connect(IP, Port);
Console.WriteLine(IP + ":" + Port + " is active");
return true;
}
catch(SocketException e)
{
Console.WriteLine("Connection could not be established due to: \n" + e.Message);
Thread.Sleep(RunEvery);
}
finally
{
client.Close();
}
}
return false;
}

Error Handling in TcpClient Socket

I am new to Sockets this is my Code to send and receive data from a server.
This Code Works fine as long as the Client is able to receive data from the server.
In Case the Server does not sends the answer back in the given time then the application needs to send "No Answer Received".
How can i know if the recvBuffer is empty or NULL.
Currently the if Condition for the recvBuffer does not work and the application tries to send empty buffer which results in "System.IndexOutOfRangeException error".
class GetSocket
{
public string SocketSendReceive(string server, int port, string cmd)
{
byte[] recvBuffer = new byte[1024];
TcpClient tcpClient = new TcpClient();
tcpClient.Client.ReceiveTimeout = 200;
try
{
tcpClient.Connect(server, 6100);
}
catch (SocketException e)
{
MessageBox.Show(e.Message);
}
if (tcpClient != null && tcpClient.Connected)
{
try
{
tcpClient.Client.Send(Encoding.UTF8.GetBytes(cmd));
tcpClient.Client.Receive(recvBuffer);
}
catch (SocketException e)
{
MessageBox.Show(e.ErrorCode.ToString());
}
tcpClient.GetStream().Close();
tcpClient.Client.Close();
tcpClient.Client.Dispose();
tcpClient = null;
string tmp = Encoding.ASCII.GetString(recvBuffer, 0, recvBuffer.Length);
if (recvBuffer != null && recvBuffer.Length > 0)
{
string[] words = tmp.Split(null);
return words[1];
}
else
{
return ("No Answer Received");
}
}
return null;
}
}
The Following code works fine after making changes as suggested.
class GetSocket
{
public string SocketSendReceive(string server, int port, string cmd)
{
byte[] recvBuffer = new byte[1024];
TcpClient tcpClient = new TcpClient();
tcpClient.Client.ReceiveTimeout = 200;
string tmp;
try
{
tcpClient.Connect(server, 6100);
}
catch (SocketException e)
{
MessageBox.Show(e.Message);
}
if (tcpClient != null && tcpClient.Connected)
{
try
{
tcpClient.Client.Send(Encoding.UTF8.GetBytes(cmd));
tcpClient.Client.Receive(recvBuffer);
tmp = Encoding.ASCII.GetString(recvBuffer, 0, recvBuffer.Length);
string[] words = tmp.Split(null);
return words[1];
}
catch (SocketException e)
{
return ("No Answer Received");
}
}
return null;
}
}

Socket Error 10054 : Error Handling Issue

Eveyone.
How to resolve the Error code 10054 ? There are some description about this error. Here is my full source code for communication. I want to know whether my code is ok or not.
WSAECONNRESET10054 Connection reset by peer. An existing connection
was forcibly closed by the remote host. This normally results if the
peer application on the remote host is suddenly stopped, the host is
rebooted, the host or remote network interface is disabled, or the
remote host uses a hard close (see setsockopt for more information on
the SO_LINGER option on the remote socket). This error may also result
if a connection was broken due to keep-alive activity detecting a
failure while one or more operations are in progress. Operations that
were in progress fail with WSAENETRESET. Subsequent operations fail
with WSAECONNRESET.
Full Source Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Threading;
using LogManager;
namespace CoreUnitPlatform
{
public class SocketCommCoreUnit
{
#region property
private volatile bool _shouldStop;
private LogWriter log = LogWriter.Instance;
private bool m_bSocketConnected = false;
private Socket m_clientSocket = null;
private SocketCommType m_connectedSockType;
private EventHandlerDataReceived m_evtHandlerDataReceived;
private EventHandlerSocketConnected m_evtHandlerSocketConnected;
private EventHandlerSocketConnectedFailed m_evtHandlerSocketConnectedFailed;
private EventHandlerSocketDisconnected m_evtHandlerSocketDisconnected;
private IPAddress m_IPAddress;
private IPEndPoint m_IPEndPoint;
private int m_portNo;
private Socket m_serverSocket = null;
private Thread m_threadConnectSocket = null;
private string Name = string.Empty;
#endregion
#region constructor
public SocketCommCoreUnit()
{
this.Name = "SocketCommCoreUnit";
Instance();
}
#endregion
#region delegatge
public delegate void EventHandlerDataReceived(string msg);
public delegate void EventHandlerSocketConnected();
public delegate void EventHandlerSocketConnectedFailed();
public delegate void EventHandlerSocketDisconnected();
public enum SocketCommType { SERVER, CLIENT };
public bool SocketConnected
{
get { lock (this) { return m_bSocketConnected; } }
set { lock (this) { m_bSocketConnected = value; } }
}
#endregion
#region public
public void ConnectSocketProc()
{
while (!_shouldStop)
{
try
{
if (SocketConnected == false)
{
if (m_connectedSockType == SocketCommType.SERVER)
{
m_clientSocket = m_serverSocket.Accept(); // If a client is connected, wait for data from client
m_evtHandlerSocketConnected();
SocketConnected = true;
}
else
{
m_clientSocket.Connect(m_IPAddress, m_portNo);
if (m_clientSocket.Connected == true)
{
m_evtHandlerSocketConnected();
SocketConnected = true;
}
}
}
else
{
try
{
byte[] buffer = new byte[1024];
int readBytes = this.m_clientSocket.Receive(buffer);
if (readBytes == 0)
{
this.reConnect();
}
else
{
string received = System.Text.Encoding.ASCII.GetString(buffer);
m_evtHandlerDataReceived(received);
}
}
catch (SocketException sex)
{
if (sex.NativeErrorCode.Equals(10054))
{
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured [{0}]: MESASGE[{1}]\r\nSOURCE[{2}]\r\nTRACE[{3}]", sex.NativeErrorCode, sex.Message, sex.Source, sex.StackTrace));
this.reConnect();
}
}
}
}
catch
{
m_evtHandlerSocketConnectedFailed();
}
Thread.Sleep(100);
}
}
public void Initialize(string IP, int port, SocketCommType sockType, EventHandlerDataReceived evtHandlerDataReceived, EventHandlerSocketConnected evtHandlerDataConnected, EventHandlerSocketDisconnected evtHandlerSocketDisconnected, EventHandlerSocketConnectedFailed evtHandlerSocketConnectedFailed)
{
m_connectedSockType = sockType;
m_evtHandlerDataReceived = evtHandlerDataReceived;
m_evtHandlerSocketDisconnected = evtHandlerSocketDisconnected;
m_evtHandlerSocketConnected = evtHandlerDataConnected;
m_evtHandlerSocketConnectedFailed = evtHandlerSocketConnectedFailed;
m_portNo = port;
m_IPAddress = IPAddress.Parse(IP);
m_IPEndPoint = new IPEndPoint(m_IPAddress, m_portNo);
if (sockType == SocketCommType.SERVER)
{
OpenServer();
}
else
{
OpenClient();
}
}
public void Instance()
{
}
public void OpenClient()
{
try
{
#if _NO_USE_SOCKET
#else
RunClientSocket();
#endif
}
catch (System.Exception ex)
{
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured: MESASGE[{0}]\r\nSOURCE[{1}]\r\nTRACE[{2}]", ex.Message, ex.Source, ex.StackTrace));
}
}
public void OpenServer()
{
try
{
#if _NO_USE_SOCKET
#else
RunServerSocket();
#endif
}
catch (System.Exception ex)
{
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured: MESASGE[{0}]\r\nSOURCE[{1}]\r\nTRACE[{2}]", ex.Message, ex.Source, ex.StackTrace));
}
}
public void Release()
{
try
{
if (this.m_clientSocket != null && this.m_clientSocket.Connected)
{
SocketConnected = false;
m_evtHandlerSocketDisconnected();
this.m_clientSocket.Shutdown(SocketShutdown.Both);
this.m_clientSocket.Close();
}
if (m_serverSocket != null)
{
m_serverSocket.Close();
}
if ((m_threadConnectSocket != null) && (m_threadConnectSocket.IsAlive == true))
{
Thread.Sleep(1);
RequestStop();
SocketConnected = false;
m_threadConnectSocket.Abort();
m_threadConnectSocket.Join();
}
}
catch (System.Exception ex)
{
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured: MESASGE[{0}]\r\nSOURCE[{1}]\r\nTRACE[{2}]", ex.Message, ex.Source, ex.StackTrace));
}
}
public void RequestStop()
{
_shouldStop = true;
}
public void RunClientSocket()
{
m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ConfigureTcpSocket(m_clientSocket, SocketCommType.CLIENT);
m_threadConnectSocket = new Thread(new ThreadStart(ConnectSocketProc));
m_threadConnectSocket.Start();
}
public void RunServerSocket()
{
m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_serverSocket.Bind(m_IPEndPoint);
m_serverSocket.Blocking = true; // The server socket is working in blocking mode
ConfigureTcpSocket(m_serverSocket, SocketCommType.SERVER);
m_serverSocket.Listen(1);
m_threadConnectSocket = new Thread(new ThreadStart(ConnectSocketProc));
m_threadConnectSocket.Start();
}
public void Send(byte[] msg)
{
#if _NO_USE_SOCKET
#else
if (SocketConnected == false)
{
throw new Exception("SOCKET_NOT_CONNECT_BEFORE_SEND_DATA;");
}
try
{
m_clientSocket.Send(msg);
}
catch (System.Exception ex)
{
SocketConnected = false;
m_evtHandlerSocketDisconnected();
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured: MESASGE[{0}]\r\nSOURCE[{1}]\r\nTRACE[{2}]", ex.Message, ex.Source, ex.StackTrace));
}
#endif
}
#endregion
#region private
private void ConfigureTcpSocket(Socket tcpSocket, SocketCommType socketCommType)
{
//// Don't allow another socket to bind to this port.
//tcpSocket.ExclusiveAddressUse = true;
//// The socket will linger for 10 seconds after
//// Socket.Close is called.
//tcpSocket.LingerState = new LingerOption(true, 10);
// Disable the Nagle Algorithm for this tcp socket.
tcpSocket.NoDelay = true;
//if (socketCommType == SocketCommType.CLIENT)
//{
// tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);
// tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// //tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
// //tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 3000);
// // Set the receive buffer size to 8k
// tcpSocket.ReceiveBufferSize = 2048;
// // Set the send buffer size to 8k.
// tcpSocket.SendBufferSize = 2048;
//}
//// Set the receive buffer size to 8k
//tcpSocket.ReceiveBufferSize = 1024;
// Set the timeout for synchronous receive methods to
// 1 second (1000 milliseconds.)
//tcpSocket.ReceiveTimeout = 1000;
//// Set the send buffer size to 8k.
//tcpSocket.SendBufferSize = 1024;
// Set the timeout for synchronous send methods
// to 1 second (1000 milliseconds.)
//tcpSocket.SendTimeout = 1000;
//// Set the Time To Live (TTL) to 42 router hops.
//tcpSocket.Ttl = 42;
}
private void ConfigureTcpSocket(Socket tcpSocket)
{
//// Don't allow another socket to bind to this port.
//tcpSocket.ExclusiveAddressUse = true;
//// The socket will linger for 10 seconds after
//// Socket.Close is called.
//tcpSocket.LingerState = new LingerOption(true, 10);
// Disable the Nagle Algorithm for this tcp socket.
tcpSocket.NoDelay = true;
//// Set the receive buffer size to 8k
//tcpSocket.ReceiveBufferSize = 8192;
// Set the timeout for synchronous receive methods to
// 1 second (1000 milliseconds.)
//tcpSocket.ReceiveTimeout = 1000;
//// Set the send buffer size to 8k.
//tcpSocket.SendBufferSize = 8192;
// Set the timeout for synchronous send methods
// to 1 second (1000 milliseconds.)
//tcpSocket.SendTimeout = 1000;
//// Set the Time To Live (TTL) to 42 router hops.
//tcpSocket.Ttl = 42;
}
private void reConnect()
{
try
{
SocketConnected = false;
m_evtHandlerSocketDisconnected();
m_clientSocket.Disconnect(true);
log.AddSystemLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Try Re-Connection..."));
if (m_connectedSockType == SocketCommType.SERVER)
{
}
else
{
m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
}
catch (System.Exception exc)
{
log.AddErrorLog(this.Name, MethodBase.GetCurrentMethod().Name, string.Format("Error Occured: MESASGE[{0}]\r\nSOURCE[{1}]\r\nTRACE[{2}]", exc.Message, exc.Source, exc.StackTrace));
}
}
#endregion
}
}
I made a (IMOHO) nice post about async sockets here, It has some pseudo code about server/client sockets.
Article: Unable to read data correctly from .Net socket in C#
I think the code of Asynchronous example is great.

Categories