Ast*_*aut 1 .net c# sockets exception
这是一个MoSync应用与外部DLL之间的本地通讯,MoSync不允许我使用第三部分DLL文件,这就是为什么我要实现的,而不是用简单的调用一个DLL此桥软件的原因,我不得不从xml转换为DLL Message格式,再转换为XML.我知道这是一个愚蠢的事情,遗憾的是没有灵活性来改变架构.最初我认为只有一个请求,所以我有Sync com,但现在我发现可以有多个请求,所以我需要再次实现Async.
我有一个异常,不时抛出,因为我是C#的新手,我无法找到内存泄漏...也许一对训练有素的眼睛可以找到问题
源代码:
我写了下面的代码,我对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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
最可能的问题是,您希望对客户端执行的三次"写入"进行三次"读取"操作.
这是一个错误的假设,因为TCP套接字是一个字节流,并不保留您的应用程序消息边界.服务器可能会消耗客户端在一次,两次或十七次读取中发送的这三个"消息".
您需要以某种方式告诉服务器消息在字节流中的结束位置.通常的选择是固定长度的消息,分隔符,指示有效负载长度的消息头,自我描述的形式,如XML等.
因此,您继续从流中读取,直到您有完整的处理消息,但同时您可能已将下一条消息的一部分读入缓冲区.
归档时间: |
|
查看次数: |
2085 次 |
最近记录: |