这是用于MoSync应用程序和外部DLL之间的本地通信,MoSync不允许使用第三部分DLL,这就是为什么我必须实现此桥接软件而不是使用简单调用的原因到一个DLL,我必须从XML转换到DLL消息格式,并再次转换为XML。我知道这是一件愚蠢的事情,不幸的是没有灵活性来改变架构。起初我以为只有一个请求,所以我有Sync com,但现在我发现可以有多个请求,所以我需要再次实现Async。EndRead引发IO异常
我有一个是从时间抛出来时的异常,因为我是新来的C#我无法找到内存泄漏......也许一对更训练有素的眼睛可以发现问题
SOURCE代码:
我写了下面的代码,我对C#和套接字很陌生,所以也许我犯了一些只有经验丰富的眼睛才能察觉的大错误。这是用于Windows Mobile 6.1设备,所以我试图避免使用很多线程。
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Diagnostics;
namespace SmartDevice_Server
{
//ClientConnection saves connection information is used to keep context in Async and Event calls
public class ClientConnection : EventArgs
{
public NetworkStream NetworkStream { get; private set; }
public byte[] Data { get; private set; }
public int byteReadCount { get; set; }
public ClientConnection(NetworkStream networkStream, byte[] data)
{
NetworkStream = networkStream;
Data = data;
}
}
//MySocket - Is a server that listens for events and triggers Events upon Request Completion
public class MySocketTCP
{
#region Class Members
TcpListener myTcpListener;
TcpClient myTcpClient;
NetworkStream myNetworkStream;
const string localHost = "127.0.0.1";
IPAddress myAddress = IPAddress.Parse(localHost);
int myPortNumber = 58889;
byte[] myData;
int bytesReadCount;
const int MIN_REQUEST_STRING_SIZE = 10;
int TimeStart;
//Event
public event socketReadCompleteHandler socketReadCompleteEvent;
public EventArgs eventArguments = null;
public delegate void socketReadCompleteHandler(MySocketTCP myTcpSocket, ClientConnection eventArguments);
#endregion
//Constructor
public MySocketTCP()
{
Init();
}
//Constructor overloaded to receive IPAdress Host, and Port number
public MySocketTCP(IPAddress hostAddress, int portNumber)
{
myAddress = hostAddress;
myPortNumber = portNumber;
Init();
}
//Initializes the TCPListner
public void Init()
{
try
{
myTcpListener = new TcpListener(myAddress, myPortNumber);
//myNetworkStream = myTcpClient.GetStream();
}
catch (Exception ex)
{
throw ex;
}
}
/*TODO_Listener_Timer: After you accept a connection you wait for data to be Read indefinitely
*Possible solution: Use a timeout to close the socket connection.
*Check WIKI, TODOS
* */
//Listens Asynchronously to Clients, class a recieveMessageHandler to process the read
public void ListenAsync()
{
myTcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
myTcpClient = myTcpListener.AcceptTcpClient();
var client = new ClientConnection(myTcpClient.GetStream(), new byte[myTcpClient.ReceiveBufferSize]);
// Capture the specific client and pass it to the receive handler
client.NetworkStream.BeginRead(client.Data, 0, client.Data.Length, r => receiveMessageHandler(r, client), null);
}
}
//Callback is used to Process the request Asynchronously, triggers socketReadCompleteEvent
public void receiveMessageHandler(IAsyncResult asyncResult, ClientConnection clientInstance)
{
bytesReadCount = 0;
lock (clientInstance.NetworkStream)
{
try
{
bytesReadCount = clientInstance.NetworkStream.EndRead(asyncResult);
clientInstance.byteReadCount = bytesReadCount;
}
catch (Exception exc)
{
throw exc;
}
}
if (bytesReadCount < MIN_REQUEST_STRING_SIZE)
{
//Could not read form client.
Debug.WriteLine("NO DATA READ");
}
else
{
if (socketReadCompleteEvent != null)
{
socketReadCompleteEvent(this, clientInstance);
}
}
}
//Reads the request, uses the ClientConnection for context
public string ReadAsync(ClientConnection connObj)
{
int bytesReadCount = connObj.byteReadCount;
byte[] myData = connObj.Data;
string xmlMessage;
try
{
xmlMessage = Encoding.ASCII.GetString(myData, 0, bytesReadCount);
}
catch (Exception ex)
{
throw ex;
}
return xmlMessage;
}
//Deprecated
public string Read()
{
string xmlMessage;
try
{
xmlMessage = Encoding.ASCII.GetString(myData, 0, bytesReadCount);
}
catch (Exception ex)
{
throw ex;
}
return xmlMessage;
}
//Deprecated
public void Write(byte[] outBytes)
{
try
{
myNetworkStream.Write(outBytes, 0, outBytes.Length);
}
catch (Exception ex)
{
throw ex;
}
}
//Deprecated
public void Write(string outMessage)
{
byte[] outBytes = Encoding.ASCII.GetBytes(outMessage);
try
{
myNetworkStream.Write(outBytes, 0, outBytes.Length);
}
catch (Exception ex)
{
throw ex;
}
int TimeEnd = Environment.TickCount;
int TimeResult = TimeEnd - TimeStart;
}
//Is used to send the message to the correct socket
public void WriteAsync(ClientConnection connObj, string outMessage)
{
byte[] outBytes = Encoding.ASCII.GetBytes(outMessage);
try
{
connObj.NetworkStream.Write(outBytes, 0, outBytes.Length);
}
catch (Exception ex)
{
throw ex;
}
int TimeEnd = Environment.TickCount;
int TimeResult = TimeEnd - TimeStart;
}
//Closes the client
public void Close()
{
//myNetworkStream.Close();
try
{
myTcpClient.Close();
}
catch (Exception ex)
{
throw ex;
}
}
}
}
你是什么意思“3个请求” ?你期望读的三条消息? –
正确,三条消息一个接一个地发送到服务器。 – Astronaut
您每次通过while循环创建一个新的TCP客户端。读完数据后需要处置或关闭它。此外,为什么每次他们想要发送数据时都要求客户端进程重新连接?这需要TCP层的大量开销。 – user957902