gpt4 book ai didi

c# - index 和 count 必须引用缓冲区中的位置。参数名称字节

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

它抛出一个索引并且计数必须引用缓冲区中的一个位置。当超过 3 个客户端连接到服务器时,参数名称字节异常 & 字节数据被声明为全局变量。

private void OnReceive(IAsyncResult ar)        
{
try
{
clientSocket.EndReceive(ar);

Data msgReceived = new Data(byteData);
//Accordingly process the message received
switch (msgReceived.cmdCommand)
{
case Command.Login:
//lstChatters.Items.Add(msgReceived.strName);
break;

case Command.Logout:
lstChatters.Items.Remove(msgReceived.strName);
break;

case Command.Message:
break;

case Command.List:
lstChatters.Items.AddRange(msgReceived.strMessage.Split('*'));
lstChatters.Items.RemoveAt(lstChatters.Items.Count - 1);
txtChatBox.Text += "<<<" + strName + " has joined the room>>>\r\n";
break;
}

if (msgReceived.strMessage != null && msgReceived.cmdCommand != Command.List)
txtChatBox.Text += msgReceived.strMessage + "\r\n";

byteData = new byte[1024];

clientSocket.BeginReceive(byteData,
0,
byteData.Length,
SocketFlags.None,
new AsyncCallback(OnReceive),
null);

}
catch (ObjectDisposedException)
{ }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "ClientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

这是用于管理服务器和客户端之间数据通信的类数据:

class Data
{
//Default constructor
public Data()
{
this.cmdCommand = Command.Null;
this.strMessage = null;
this.strName = null;
}

//Converts the bytes into an object of type Data
public Data(byte[] data)
{
//The first four bytes are for the Command
this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);

//The next four store the length of the name
int nameLen = BitConverter.ToInt32(data, 4);

//The next four store the length of the message
int msgLen = BitConverter.ToInt32(data, 8);

//This check makes sure that strName has been passed in the array of bytes
if (nameLen > 0)
this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
else
this.strName = null;

//This checks for a null message field
if (msgLen > 0)
this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
else
this.strMessage = null;
}

//Converts the Data structure into an array of bytes
public byte[] ToByte()
{
List<byte> result = new List<byte>();

//First four are for the Command
result.AddRange(BitConverter.GetBytes((int)cmdCommand));

//Add the length of the name
if (strName != null)
result.AddRange(BitConverter.GetBytes(strName.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Length of the message
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(strMessage.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Add the name
if (strName != null)
result.AddRange(Encoding.UTF8.GetBytes(strName));

//And, lastly we add the message text to our array of bytes
if (strMessage != null)
result.AddRange(Encoding.UTF8.GetBytes(strMessage));

return result.ToArray();
}

public string strName; //Name by which the client logs into the room
public string strMessage; //Message text
public Command cmdCommand; //Command type (login, logout, send message, etcetera)
}

最佳答案

要解决第一个 问题,不要让byteData 成为全局的。改为本地化:

private void OnReceive(IAsyncResult ar)        
{
byte[] byteData;

然后,将其作为 state 参数传递给 BeginReceive :

 byteData = new byte[1024]; //Line 1

clientSocket.BeginReceive(byteData,
0,
byteData.Length,
SocketFlags.None,
new AsyncCallback(OnReceive),
byteData);

然后从 IAsyncResult 中恢复它在您完成接收后使用它之前:

clientSocket.EndReceive(ar);
byteData = (byte[])ar.AsyncState;

Data msgReceived = new Data(byteData); //Line2

当然,解决了这个问题后,您仍然遇到我在评论中提到的另一个问题 - 无法保证有多少数据将返回到缓冲区中 - 您需要检查 EndReceive 的返回值.您可能必须组合多次调用 Receive(或它的道德等价物),直到您真正建立一条消息。在一端调用 Send 和在另一端调用 Receive 之间没有一对一的对应关系。

最后,您已经表明您正在使用 TcpClient,但您正在使用来自 Socket 类的操作?为什么您不使用 TcpClient 提供的 NetworkStream? (并不是说它在这里有太大的不同)。

关于c# - index 和 count 必须引用缓冲区中的位置。参数名称字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12419121/

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