gpt4 book ai didi

c# - EndRead引发IO异常

转载 作者:太空宇宙 更新时间:2023-11-03 17:54:50 25 4
gpt4 key购买 nike

这是用于MoSync应用程序和外部DLL之间的本地通信的,MoSync不允许我使用第三部分DLL,这就是为什么我必须实现此桥软件而不是使用对DLL的简单调用的原因,我必须从xml转换为DLL消息格式,然后再次转换为XML。我知道这是一个愚蠢的事情,不幸的是,更改体系结构没有灵活性。最初我以为只有一个请求,所以我有了Sync coms,但是现在我发现可以有多个请求,因此我需要再次实现Async。

我不时抛出一个异常,因为我是C#的新手,所以我找不到内存泄漏...也许一双训练有素的眼睛可以找到问题。

源代码:

我编写了以下代码,因为我对C#和Sockets还是很陌生,所以也许我犯了一些大错误,只有经验丰富的眼睛才能发现。这将在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;
}
}
}
}

最佳答案

最可能的问题是,您期望为客户端执行的三个“写入”操作恰好执行三个“读取”操作。

这是一个错误的假设,因为TCP套接字是一个字节流,并且不保留您的应用程序消息边界。服务器可能会在一次,两次或十七次读取中使用客户端发送的这三个“消息”。

您需要以某种方式告诉服务器消息在字节流中的结束位置。通常的选择是固定长度的消息,定界符,指示有效负载长度的消息头,自描述形式(如XML)等。

因此,您可以继续从流中读取消息,直到有完整的消息要处理为止,但是与此同时,下一条消息的一部分可能已经被读入缓冲区。

关于c# - EndRead引发IO异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13957321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com