Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 索引和计数必须引用缓冲区中的位置。参数名字节_C#_Bytearray_Tcpclient - Fatal编程技术网

C# 索引和计数必须引用缓冲区中的位置。参数名字节

C# 索引和计数必须引用缓冲区中的位置。参数名字节,c#,bytearray,tcpclient,C#,Bytearray,Tcpclient,它抛出一个索引,计数必须引用缓冲区中的一个位置。当连接到服务器的客户端超过3个时,参数名称字节异常&字节数据声明为全局变量 private void OnReceive(IAsyncResult ar) { try { clientSocket.EndReceive(ar); Data msgReceived = new Data(byteData); //Accordingly proces

它抛出一个索引,计数必须引用缓冲区中的一个位置。当连接到服务器的客户端超过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);
    }
}
private void OnReceive(IAsyncResult ar)
{           
尝试
{
clientSocket.EndReceive(ar);
数据msgReceived=新数据(byteData);
//相应地处理收到的消息
开关(msgReceived.cmdCommand)
{
case命令。登录:
//lstChatters.Items.Add(msgReceived.strName);
打破
case命令。注销:
lstChatters.Items.Remove(msgReceived.strName);
打破
case命令。消息:
打破
case命令。列表:
lstChatters.Items.AddRange(msgReceived.strMessage.Split('*');
lstChatters.Items.RemoveAt(lstChatters.Items.Count-1);
txtChatBox.Text+=“\r\n”;
打破
}
if(msgReceived.strMessage!=null&&msgReceived.cmdCommand!=Command.List)
txtChatBox.Text+=msgReceived.strMessage+“\r\n”;
byteData=新字节[1024];
clientSocket.BeginReceive(byteData,
0,
byteData.长度,
SocketFlags,没有,
新异步回调(OnReceive),
无效);
}
捕获(ObjectDisposedException)
{ }
捕获(例外情况除外)
{
MessageBox.Show(例如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)
}
类数据
{
//默认构造函数
公共数据()
{
this.cmdCommand=Command.Null;
this.strMessage=null;
this.strName=null;
}
//将字节转换为数据类型的对象
公共数据(字节[]数据)
{
//前四个字节用于命令
this.cmdCommand=(命令)BitConverter.ToInt32(数据,0);
//接下来的四个存储名称的长度
int nameLen=BitConverter.ToInt32(数据,4);
//接下来的四个存储消息的长度
int msgLen=BitConverter.ToInt32(数据,8);
//此检查确保strName已在字节数组中传递
如果(名称>0)
this.strName=Encoding.UTF8.GetString(数据,12,nameLen);
其他的
this.strName=null;
//这将检查是否存在空消息字段
如果(msgLen>0)
this.strMessage=Encoding.UTF8.GetString(数据,12+nameLen,msgLen);
其他的
this.strMessage=null;
}
//将数据结构转换为字节数组
公共字节[]ToByte()
{
列表结果=新列表();
//前四个用于命令
AddRange(BitConverter.GetBytes((int)cmdCommand));
//添加名称的长度
if(strName!=null)
AddRange(BitConverter.GetBytes(strName.Length));
其他的
result.AddRange(BitConverter.GetBytes(0));
//信息的长度
if(strMessage!=null)
AddRange(BitConverter.GetBytes(strMessage.Length));
其他的
result.AddRange(BitConverter.GetBytes(0));
//添加名称
if(strName!=null)
AddRange(Encoding.UTF8.GetBytes(strName));
//最后,我们将消息文本添加到字节数组中
if(strMessage!=null)
AddRange(Encoding.UTF8.GetBytes(strMessage));
返回result.ToArray();
}
public string strName;//客户端登录文件室时使用的名称
公共字符串strMessage;//消息文本
公共命令cmdCommand;//命令类型(登录、注销、发送消息等)
}
要解决第一个问题,请不要将
字节数据作为全局变量。将其改为本地:

private void OnReceive(IAsyncResult ar)        
{          
    byte[] byteData;
然后,将其作为
状态
参数传递给:

当您完成接收后,在使用之前从中恢复:

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

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

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

最后,您已经指出您正在使用
TcpClient
,但是您正在使用
Socket
类中的操作?您为什么不使用
TcpClient
提供给您的
NetworkStream
?(这并不是说它在这里有太大的区别)。

要解决第一个问题,请不要将
字节数据作为全局变量。将其改为本地:

private void OnReceive(IAsyncResult ar)        
{          
    byte[] byteData;
然后,将其作为
状态
参数传递给:

当您完成接收后,在使用之前从中恢复:

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

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

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

最后,您已经指出您正在使用
TcpClient
,但是您正在使用
Socket
类中的操作?有什么原因吗