这是我的情景: 客户: 连续24/7连续发送xml数据 - (它工作正常,不在我的控制之下)。 服务器 - 我的代码: 1.不断听。 2.接收传入消息,缓冲它并从缓冲区创建有效的xml。 3.将其发送到MSMQ(主机将执行此操作)
我写了一个tcp服务器代码(从谷歌添加代码片段),它将在Windows服务中托管。当我在本地运行服务时,一切正常,但是当我将它放置PROD时,它会监听多达73K的消息,并且它会停止接收。它没有抛出任何异常。它只是阻止 BeginReceive 功能。我也尝试过使用ReceiveTimeOut。我也见过netstat,连接仍然是已建立的统计数据。 当我重新启动服务时,它再次正常工作。我在这里发布我的服务器代码。请帮忙。
StringBuilder content = new StringBuilder();
public event MessageReceiveEventHandler MessageReceived;
// An ArrayList is used to keep track of worker sockets that are designed
// to communicate with each connected client. Make it a synchronized ArrayList
// For thread safety
private System.Collections.ArrayList workerSocketList =
ArrayList.Synchronized(new System.Collections.ArrayList());
private int m_clientCount = 0;
private Socket m_mainSocket = null;
private AsyncCallback ReadCallback;
private AsyncCallback ConnectionCallback;
public MedDeviceListener(string ipAddress, int port, int maxConnections=100)
{
ProfileProvider.Instance.LogInformationIf(_debug);
this._port = port;
this._ipAddress = ipAddress;
this._maxConnections = maxConnections;
ReadCallback = new AsyncCallback(Receive_handler);
ConnectionCallback = new AsyncCallback(Connection_handler);
lenghtofStartMsg = header.Length;
lengthOfEndMsg = footer.Length;
}
public void Start()
{
ProfileProvider.Instance.LogInformationIf(_debug);
// Data buffer for incoming data.
byte[] bytes = new Byte[_bufferSize];
// Establish the local endpoint for the socket.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);
// Create a TCP/IP socket.
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
m_mainSocket.Bind(localEndPoint);
m_mainSocket.Listen(100);
InstrumentationProvider.Instance.LogInformation("MedDeviceListener successfully connected to IP:" + _ipAddress+"\nPort :"+_port);
m_mainSocket.BeginAccept(ConnectionCallback, m_mainSocket);
}
catch (Exception e)
{
InstrumentationProvider.Instance.LogException("MedDeviceListener.Start", e);
throw e;
}
}
private void Connection_handler(IAsyncResult ar)
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
Socket listener = (Socket)ar.AsyncState;
Socket workerSocket = listener.EndAccept(ar);
// Now increment the client count for this client
// in a thread safe manner
Interlocked.Increment(ref m_clientCount);
// Add the workerSocket reference to our ArrayList
workerSocketList.Add(workerSocket);
SendConnectedAck(_clientConnectAckMessage, m_clientCount);
WaitForData(workerSocket, m_clientCount);
//Resume the listening callback loop
listener.BeginAccept(Connection_handler, listener);
}
catch (ObjectDisposedException)
{
InstrumentationProvider.Instance.LogInformation("The listener socket has been closed");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("Connection_handler", ex);
throw;
}
}
private void Receive_handler(IAsyncResult ar)
{
ProfileProvider.Instance.LogInformationIf(_debug);
StateObject state = (StateObject)ar.AsyncState;
try
{
// Retrieve the state object and the handler socket
// from the asynchronous state object.
Socket workSocket = state.workSocket;
// Read data from the client socket.
int bytesRead = workSocket.EndReceive(ar);
if (bytesRead > 0)
{
//InstrumentationProvider.Instance.LogInformationIf(_debug, bytesRead+" read..");
// There might be more data, so parse the data received so far.
string data= Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
try
{
ParseIncomingMessage(data, workSocket);
}
catch(Exception parseEx)
{
content.Clear();
InstrumentationProvider.Instance.LogException("ParseIncomingMessage", parseEx);
}
}
WaitForData(state.workSocket, state.clientNumber);
}
catch (ObjectDisposedException)
{
InstrumentationProvider.Instance.LogInformation("Receive_handler: The listener socket has been closed");
}
catch (SocketException se)
{
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
}
private void WaitForData(Socket workerSocket, int clientNumber)
{
ProfileProvider.Instance.LogInformationIf(_debug);
try
{
StateObject theSocPkt = new StateObject(workerSocket, clientNumber);
workerSocket.ReceiveTimeout = 2000;
workerSocket.BeginReceive(theSocPkt.buffer, 0,
theSocPkt.buffer.Length,
SocketFlags.None,
Receive_handler,
theSocPkt);
}
catch(TimeoutException ex)
{
InstrumentationProvider.Instance.LogException("WaitForData - TimeOutException", ex);
}
catch (SocketException se)
{
InstrumentationProvider.Instance.LogException("MedDeviceListener.WaitForData", se);
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("WaitForData",ex);
//close the existing connection
CloseSockets();
//restart it again
this.Start();
}
}
private void ParseIncomingMessage(string msg,Socket wrkSocket)
{
Socket workSocket = wrkSocket;
bool hasStartTag = isMsgContainsStartTag(msg);
bool hasEndTag = isMsgContainsEndTag(msg);
int startTagIndex = indexOfStartTag(msg);
int endTagIndex = indexOfEndTag(msg);
// If the incomming message dont have either start or end tag
if (hasStartTag == false && hasEndTag == false)
{
content.Append(msg);
}
//check for the starttag first
//if message contains startTag
else if (hasStartTag)
{
if (startTagIndex != 0)//there is something before starttag
{
string subStr = msg.Substring(0, startTagIndex);
content.Append(subStr);
//Check and send the content
CheckSendMessage(workSocket);
//Parse the remaining message from start tag to end of the message
ParseIncomingMessage(msg.Substring(startTagIndex, msg.Length - subStr.Length), wrkSocket);
}
else if (startTagIndex == 0)
{
content.Clear();
if (hasEndTag)
{
int endOfEndTag = endTagIndex + lengthOfEndMsg;
string subStr = msg.Substring(0, endOfEndTag); //message statrs with start tag and ends contains full end tag so first get that string and send that.
content.Append(subStr);
CheckSendMessage(workSocket);
//Parse the remaining message from endtag+1 to end
ParseIncomingMessage(msg.Substring(endOfEndTag, msg.Length - endOfEndTag), wrkSocket);
}
else
{
content.Append(msg);
}
}
}
//if message contains EndTag ALONE
else if (hasEndTag)
{
int endOfEndTag = endTagIndex + lengthOfEndMsg;
string subStr = msg.Substring(0, endOfEndTag);
content.Append(subStr);
CheckSendMessage(workSocket);
//Parse remaining message after end tag
ParseIncomingMessage(msg.Substring(endOfEndTag, msg.Length - endOfEndTag), wrkSocket);
}
}
private void CheckSendMessage(Socket workSocket)
{
string msg=content.ToString().Trim();
//if content contains both start and end tag then send the content
if (isMsgContainsStartTag(msg) && isMsgContainsEndTag(msg) &&
indexOfStartTag(msg) == 0 && indexOfEndTag(msg) + lengthOfEndMsg == msg.Length)
{
//Send the message
using (MedDeviceListenerEventArgs e = new MedDeviceListenerEventArgs(msg))
{
OnReceiveComplete(e);
SendReceiveAck(workSocket, _receiveAckMessage);
}
}
}
private void SendReceiveAck(Socket handler, String data)
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
handler.Send(byteData);
InstrumentationProvider.Instance.LogInformationIf(_debug, "Message received acknowledgement:" + _receiveAckMessage + " has been sent successfully");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("SendReceiveAck", ex);
}
}
private void SendConnectedAck(string msg, int clientNumber)
{
ProfileProvider.Instance.LogInformationIf(_debug);
try
{
// Convert the reply to byte array
byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg);
Socket workerSocket = (Socket)workerSocketList[clientNumber - 1];
workerSocket.Send(byData);
InstrumentationProvider.Instance.LogInformationIf(_debug, "Client Connected acknowledgement:" + _clientConnectAckMessage + " has been sent successfully");
}
catch (Exception ex)
{
InstrumentationProvider.Instance.LogException("SendConnectedAck", ex);
throw;
}
}
public void CloseSockets()
{
try
{
ProfileProvider.Instance.LogInformationIf(_debug);
if (m_mainSocket != null)
{
if (m_mainSocket.Connected)
{
m_mainSocket.Shutdown(SocketShutdown.Both);
m_mainSocket.Close();
m_mainSocket = null;
}
}
Socket workerSocket = null;
for (int i = 0; i < workerSocketList.Count; i++)
{
workerSocket = (Socket)workerSocketList[i];
if (workerSocket != null)
{
workerSocket.Shutdown(SocketShutdown.Both);
workerSocket.Close();
workerSocket = null;
}
}
}
catch(Exception ex)
{
InstrumentationProvider.Instance.LogException("CloseSockets",ex);
}
}
protected virtual void OnReceiveComplete(MedDeviceListenerEventArgs e)
{
if (MessageReceived != null)
{
MessageReceived(this, e);
}
}
private int indexOfStartTag(string msg)
{
return msg.IndexOf(header);
}
private int indexOfEndTag(string msg)
{
return msg.IndexOf(footer);
}
private bool isMsgContainsStartTag(string msg)
{
return msg.Contains(header);
}
private bool isMsgContainsEndTag(string msg)
{
return msg.Contains(footer);
}
public delegate void MessageReceiveEventHandler(object sender,MedDeviceListenerEventArgs e);
public class MedDeviceListenerEventArgs : EventArgs,IDisposable
{
private string _receivedData;
public MedDeviceListenerEventArgs(string receivedData)
{
_receivedData = receivedData;
}
public string ReceivedData
{
get
{
return _receivedData;
}
}
public void Dispose()
{ }
}
}
我看过类似的帖子,尝试了一切,但没有运气。请帮助:)
由于 -MM