使用tcp套接字在第二次调用网络时从网络接收不相关的数据

时间:2014-03-02 23:33:17

标签: c# sockets tcp

我的游戏有两个客户端&一台服务器。 client1通过在服务器和服务器上放置数据将数据发送到client2。 client2从服务器检索。类似地,client2通过服务器向client1发送数据。

当我从Client1向client2发送数据时,一切都很好但是当client2向client1发送数据时,它会收到不相关的数据。

我认为在第一次通信期间,服务器上的任何数据都不是清除&因此,当Clien2将数据发送回client1时,数据与服务器上的数据重叠。发送不相关的数据。

我对所有客户端使用相同的代码,但是客户端代码的多个实例。

以下是我正在使用的代码: -

       private void OnKeyDown1(object sender, KeyEventArgs e)
        {
        tbxno = 1;
        if (e.Key == Key.Enter || e.Key == Key.Return)
        {
            // Disable further edit on textbox
            playerTbx1.IsReadOnly = true;

            // Compare answers entered by user
            char[] letters = new char[playerTbx1.Text.Length];
            StringReader sr = new StringReader(playerTbx1.Text);
            sr.Read(letters, 0, playerTbx1.Text.Length);
            int c = 0;
            Console.WriteLine(word[i - 1]);
            string label = MainWordLabel.Content.ToString();

            while (label.Contains(letters[c].ToString()))
            {
                c++;
                if (c == letters.Length)
                    break;
            }
            int count = c;
            MessageBox.Show("No. of words matching : " + c);
            // Score calculation
            score += c * 5;
            PlayerScoreTbx.Text = score.ToString();

            //Send data to server
            byte[] buffer = System.Text.Encoding.ASCII.GetBytes(playerTbx1.Text);

            byte[] length = new byte[2];
            length[0] = (byte)(playerTbx1.Text.Length % 256);
            length[1] = (byte)(playerTbx1.Text.Length / 256);


            byte[] usernameBuffer = System.Text.Encoding.ASCII.GetBytes(Username_Textbox.Text);

            byte[] unamelength = new byte[2];
            unamelength[0] = (byte)(Username_Textbox.Text.Length % 256);
            unamelength[1] = (byte)(Username_Textbox.Text.Length / 256);

            byte[] scoreBuffer = System.Text.Encoding.ASCII.GetBytes(PlayerScoreTbx.Text);

            byte[] scoreLength = new byte[2];
            scoreLength[0] = (byte)(PlayerScoreTbx.Text.Length % 256);
            scoreLength[1] = (byte)(PlayerScoreTbx.Text.Length / 256);

            byte[] tno = new byte[1];
            tno[0] = (byte)tbxno;

            tcpClient.Client.Send(length);
            tcpClient.Client.Send(buffer);
            tcpClient.Client.Send(unamelength);
            tcpClient.Client.Send(usernameBuffer);
            tcpClient.Client.Send(scoreLength);
            tcpClient.Client.Send(scoreBuffer);
            tcpClient.Client.Send(tno);
        }
    }

从服务器收回数据时: -

void getdata()         {

        while (tcpsocket.Connected)
        {

            NetworkStream stream = tcpClient.GetStream();

            byte[] userName = new byte[1024];
            byte[] buffer = new byte[256];
            byte[] length = new byte[2];
            byte[] userlength = new byte[2];
            byte[] scoreBuffer = new byte[1024];
            byte[] scoreLength = new byte[2];

            // read length of username
            int readUserlength = stream.Read(userlength, 0, 2);
            int userLength = userlength[0] + (userlength[1] * 256);

            // read username
            stream.Read(userName, 0, userLength);
            string userReceived = System.Text.Encoding.ASCII.GetString(userName, 0, userLength);

            // read length of score
            int readUScore = stream.Read(scoreLength, 0, 2);
            int lengthOfScore = scoreLength[0] + (scoreLength[1] * 256);

            // read score
            stream.Read(scoreBuffer, 0, lengthOfScore);
            string score = System.Text.Encoding.ASCII.GetString(scoreBuffer, 0, lengthOfScore);

            // check if the same client is not receiving data
            this.Dispatcher.Invoke(() =>
            {
                if (userReceived.Equals(Username_Textbox.Text) == false)
                {
                    int readlength = stream.Read(length, 0, 2);
                    int dataLength = length[0] + (length[1] * 256);
                    stream.Read(buffer, 0, dataLength);
                    string data = System.Text.Encoding.ASCII.GetString(buffer,0,dataLength);

                    byte[] tbox = new byte[1];
                    stream.Read(tbox, 0, 1);


                    int count = tbox[0];

                    this.Dispatcher.Invoke(() =>
                    {
                        OppTbx1.Text = data;
                        OppScoreTbx.Text = score;
                    });


                }
            });

        }
    }

服务器上的代码: -

public delegate void Disconnected(ClientManager item);

public delegate void MessageReceived(string item, string username, string score, byte textbox);

public class ClientManager
{
    public Socket socket { get; set; }
    private NetworkStream networkStream;

    public event Disconnected OnDisconnected;
    public event MessageReceived OnMessage;


    public ClientManager(Socket clientSocket)
    {
        this.socket = clientSocket;
        this.networkStream = new NetworkStream(this.socket);
        Task.Factory.StartNew(() =>
        {
            while (socket.Connected)
            {
                // TextBox Data
                byte[] dataBuffer = new byte[1024];
                byte[] length = new byte[2];
                int readlength = this.networkStream.Read(length, 0, 2);
                if (readlength == 0)
                    break;
                int dataLength = length[0] + (length[1] * 256);
                int readDataBytes = this.networkStream.Read(dataBuffer, 0, dataLength);
                if (readDataBytes == 0)
                    break;
                string data = System.Text.Encoding.ASCII.GetString(dataBuffer, 0, dataLength);

                // Username Information
                byte[] username = new byte[1024];

                byte[] userlength = new byte[2];
                int readLengthbytes = this.networkStream.Read(userlength, 0, 2);
                if (readLengthbytes == 0)
                    break;
                int userLength = userlength[0] + (userlength[1] * 256);

                int readUsername = this.networkStream.Read(username, 0, userLength);
                if (readUsername == 0)
                    break;

                string usernameString = System.Text.Encoding.ASCII.GetString(username, 0, userLength);

                // score

                byte[] scoreBuffer = new byte[1024];

                byte[] scorLength = new byte[2];
                int readscorelength = this.networkStream.Read(scorLength, 0, 2);
                if (readscorelength == 0)
                    break;
                int lenghtOfScore = scorLength[0] + (scorLength[1] * 256);

                int readscore = this.networkStream.Read(scoreBuffer, 0, lenghtOfScore);
                if (readscore == 0)
                    break;

                string score = System.Text.Encoding.ASCII.GetString(scoreBuffer, 0, lenghtOfScore);

                byte[] tbx = new byte[1];

                this.networkStream.Read(tbx,0,1);

                //send data,sername & score
                OnMessage(data, usernameString, score, tbx[0]);


            }

            //socket.Disconnect(false);
            if (OnDisconnected != null)
                OnDisconnected(this);
        });
    }
}

}

向客户发回: -

void SendChatMessage(字符串消息,字符串用户名,字符串分数,字节tbox)         {             byte [] data = System.Text.Encoding.ASCII.GetBytes(message);             byte [] length = new byte [2];             length [0] =(byte)(message.Length%256);             length [1] =(byte)(message.Length / 256);

        byte[] usernameBuffer = System.Text.Encoding.ASCII.GetBytes(username);
        byte[] userlength = new byte[2];
        userlength[0] = (byte)(username.Length % 256);
        userlength[1] = (byte)(username.Length / 256);

        byte[] scoreBuffer = System.Text.Encoding.ASCII.GetBytes(score);
        byte[] scoreLength = new byte[2];
        scoreLength[0] = (byte)(score.Length % 256);
        scoreLength[1] = (byte)(score.Length / 256);

        byte[] tbxCount = new byte[1];
        tbxCount[0] = tbox;
        Task.Factory.StartNew(() =>
        {
            lock (tcpClients)
            {
                foreach (var item in tcpClients)
                {
                    try
                    {
                        item.socket.Send(userlength);
                        item.socket.Send(usernameBuffer);
                        item.socket.Send(scoreLength);
                        item.socket.Send(scoreBuffer);
                        item.socket.Send(length);
                        item.socket.Send(data);
                        item.socket.Send(tbxCount);

                    }
                    catch (Exception ex)
                    {
                        ex.GetBaseException();
                    }


                }
            }

        });
    }


}

1 个答案:

答案 0 :(得分:0)

正如在这些问题中看到的那样,你忽略了Read()返回的计数,并假设读取填充了缓冲区。没有指定这样做,或者传输任何多于一个字节:非阻塞模式下的零字节。您需要循环,直到您拥有所需或所需的所有数据。