我有一个异步的TCP客户端,在Windows xp 32位上工作正常,但在Windows服务器2008和2012 R2 stardard 64位上收到错误消息。不确定为什么它表现不同。
此ServerAddress参数为127.0.0.1。
1:[1]:2014/12/09 22:41:11.224-Connecting to server 127.0.0.1 port 25000
1:[5]:2014/12/09 22:41:11.224-Socket connected to 127.0.0.1:25000
3:[5]:2014/12/09 22:41:11.224-Sent 86 bytes to server.
3:[1]:2014/12/09 22:41:11.115-Thread[0001]: Wait timeout! No response message received.
3:[4]:2014/12/09 22:41:11.303-ReceiveCallback Exception:Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
代码段:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace AsynClient
{
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
class AsyncTcpClient
{
#region Private Variables
private Socket client;
// ManualResetEvent instances signal completion.
private ManualResetEvent connectDone = new ManualResetEvent(false);
private ManualResetEvent sendDone = new ManualResetEvent(false);
private ManualResetEvent receiveDone = new ManualResetEvent(false);
// The response from the remote device.
private String response = String.Empty;
private string address;
private int port;
private int timeout;
private Logger logger;
private bool bTimeout;
#endregion
public bool IsTimeout
{
get
{
return bTimeout;
}
set
{
bTimeout = value;
}
}
/// <summary>
/// Constructor for AsyncTcpClient class
/// </summary>
/// <param name="ServerAddress">The TCP/IP server that should be used for connecting</param>
/// <param name="ServerPort">The TCP/IP port that should be used for connecting</param>
/// <param name="Timeout">Timeout in seconds</param>
/// <param name="BaseLogFile">Base log file name</param>
/// <param name="logSize">Base log file size</param>
public AsyncTcpClient(string ServerAddress, int ServerPort, int Timeout, string BaseLogFile, long BaseLogSize)
{
address = ServerAddress;
port = ServerPort;
timeout = Timeout;
//provide a default log in case the component using this library does not use the logger class
logger = Logger.GetInstance();
try
{
logger.Initialize(BaseLogFile + (".LOG"), BaseLogSize);
}
catch
{
//If the init throws an exception that's OK because it means that the top level
//already initialized the component.
}
IsTimeout = false;
}
/// <summary>
/// Connnects to the remote socket server.
/// </summary>
public void Connect()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse(address); ;
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
}
catch (Exception e)
{
client.Disconnect(true);
connectDone.Reset();
logger.WriteToLogFile(string.Format("Connect Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
/// <summary>
/// Callback function called when a client tries to connect to the server
/// </summary>
/// <param name="ar">Represents the status of async result object</param>
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
logger.WriteToLogFile(string.Format("Socket connected to {0}", client.RemoteEndPoint.ToString()),
MessageType.Information, LogLevel.Basic);
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("ConnectCallback Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
Environment.Exit(0);
}
}
/// <summary>
/// Send the data to the TCP server, and wait for signal
/// </summary>
/// <param name="client">Represents the TCP server socket</param>
/// <param name="data">Represents the data</param>
public void Send(String data)
{
try
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
sendDone.WaitOne();
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("Send Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
/// <summary>
/// Callback for the send opertaion.
/// </summary>
/// <param name="ar">Represents the status of async result object</param>
public void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
// Signal that all bytes have been sent.
sendDone.Set();
logger.WriteToLogFile(string.Format("Sent {0} bytes to server.", bytesSent), MessageType.Error, LogLevel.Basic);
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("SendCallback Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
/// <summary>
/// Start listening for incoming data to this connection
/// </summary>
public void Receive()
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
//wait for the signal or timeout
bool success = receiveDone.WaitOne(timeout * 1000, false);
if (!success)
{
IsTimeout = true;
logger.WriteToLogFile(string.Format("Thread[{0:d4}]: Wait timeout! No response message received.", Thread.CurrentThread.GetHashCode()), MessageType.Error, LogLevel.Basic);
}
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("Receive Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
/// <summary>
/// Callback for the receive operation.
/// </summary>
/// <param name="result">Represents the status of async result object</param>
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
if (client.Connected)
{
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
logger.WriteToLogFile(string.Format("Response received:{0}", response), MessageType.Error, LogLevel.Basic);
}
}
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("ReceiveCallback Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
/// <summary>
/// Stops the TCP Client, closes the socket connection and releases resources.
/// </summary>
public void Stop()
{
try
{
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
logger.WriteToLogFile("Close the socket connection and release all the resourses", MessageType.Information, LogLevel.Basic);
}
catch (Exception e)
{
logger.WriteToLogFile(string.Format("Close Exception:{0}", e.Message), MessageType.Error, LogLevel.Basic);
}
}
}
}