1

出于某种原因,我的套接字正在显示在代码的另一部分中收到的数据。例如,当我登录时它工作正常,但随后我从服务器发送了一条聊天消息,它显示了从登录发送的用户名。

这是来自服务器的网络类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    using System.Windows.Forms;
    using System.IO;

    namespace Banshee_Server
    {
        class Network
        {
            public Socket listener;
            IPEndPoint localEndPoint;
            public const int BufferSize = 1024;
            public byte[] buffer = new byte[BufferSize];

            public static Dictionary<Socket, Player> dictionary = new Dictionary<Socket, Player>();

            public Player getPlayer(Socket socket)
            {
                if (socket != null)
                {
                    if(dictionary.ContainsKey(socket))
                    {
                        return dictionary[socket];
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }

            public bool playerIsLoggedIn(String player)
            {
                try
                {
                    foreach (Socket sock in dictionary.Keys)
                    {
                        if (getPlayer(sock).Name.ToLower() == player.ToLower())
                        {
                            return true;
                        }
                    }
                    return false;
                }
                catch {
                    return true;
                }
            }

            public static int getFreePlayerIndex
            {
                get { return Network.dictionary.Count(); }
            }

            netHandler handlers = new netHandler();

            public Network(Socket socket, int port)
            {
                this.listener = socket;
                localEndPoint = new IPEndPoint(IPAddress.Loopback, port);
            }

            public void bindListener()
            {
                listener.Bind(localEndPoint);
            }
            public void startListening()
            {

                try
                {

                    listener.Listen(100);
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }

            public void AcceptCallback(IAsyncResult ar){
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);
                startListening();
                handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
                Common common = new Common();
                common.appendLog("New Connection received from " + handler.RemoteEndPoint.ToString());

            }

            public void ReadCallback(IAsyncResult ar){
                Socket handler = (Socket)ar.AsyncState;
                try
                {
                    int bytesRead = handler.EndReceive(ar);

                    if (bytesRead > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        byte[] byteData = new byte[bytesRead];
                        byteData = buffer;
                        byte[] readData = new byte[byteData.Length - 1];
                        Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
                        sb.Append(Encoding.ASCII.GetString(readData));
                        String data = sb.ToString();



                        handlers.handleData(handlers.getHandlerType(byteData[0]), data, handler);

                        handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
                    }
                    else
                    {
                        handler.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), handler);
                    }
                }
                catch
                {

                }

            }

            private static void sendFileCallback(IAsyncResult ar)
            {
                Socket client = (Socket)ar.AsyncState;

                client.EndSendFile(ar);
            }

            public void Send(Socket sock, String data, byte dataType)
            {
                byte[] byteType = new byte[1];
                byteType[0] = dataType;

                int bufferSize = byteType.Length + Encoding.ASCII.GetBytes(data).Length;
                var ms = new MemoryStream(new byte[bufferSize], 0, bufferSize, true, true);
                ms.Write(byteType, 0, byteType.Length);
                ms.Write(Encoding.ASCII.GetBytes(data), 0, Encoding.ASCII.GetBytes(data).Length);

                byte[] byteData = ms.GetBuffer();

                sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
            }

            public void SendtoAll(String data, byte dataType)
            {

                try
                {
                    foreach (Socket sock in dictionary.Keys)
                    {
                        try
                        {
                            Send(sock, data, dataType);
                        }
                        catch
                        {
                            handlers.logoutPlayer(sock, this);
                        }
                    }
                }
                catch { }
            }


            private static void SendCallback(IAsyncResult ar)
            {
                try
                {

                    Socket handler = (Socket)ar.AsyncState;
                    int bytesSent = handler.EndSend(ar);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }

        }
    }

这是来自客户端的网络类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace Ghoul_Engine
{
    class network
    {

        public Socket sock;
        public const int BufferSize = 1024;
        public Byte[] buffer = new Byte[BufferSize];
        public IPEndPoint RemoteEndPoint;



        public network()
        {


        }

        public void beginConnect(Socket socket)
        {
            sock = socket;
            try
            {
                sock.BeginConnect(RemoteEndPoint, new AsyncCallback(onConnect), sock);
            }
            catch
            {
                MessageBox.Show("Could not connect to remote server. Perhaps it's down.");
            }
        }

        public void onConnect(IAsyncResult ar)
        {
            try
            {
                sock.EndConnect(ar);
                sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
            } catch{
                MessageBox.Show("Error connecting to server, it could be down!");
            }
        }

        public void ReadCallback(IAsyncResult ar)
        {
            Socket sock = (Socket)ar.AsyncState;
            try
            {
                int bytesRead = sock.EndReceive(ar);

            if (bytesRead > 0)
            {

                StringBuilder sb = new StringBuilder();
                byte[] byteData = new byte[bytesRead];
                byteData = buffer;
                byte[] readData = new byte[byteData.Length - 1];
                Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
                sb.Append(Encoding.ASCII.GetString(readData));
                String data = sb.ToString();



                Program.netHandlers.handleData(Program.netHandlers.getHandlerType(byteData[0]), data, sock);
                if(sock.Connected){
                    sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
                }
            }
            else
            {
                if(sock.Connected){
                    sock.BeginReceive(buffer, 0, BufferSize, 0, new AsyncCallback(ReadCallback), sock);
                }

            }
            }
            catch { }

        }



        public void Send(String data, byte dataType)
        {
            byte[] byteType = new byte[1];
            byteType[0] = dataType;

            int bufferSize = byteType.Length + Encoding.ASCII.GetBytes(data).Length;
            var ms = new MemoryStream(new byte[bufferSize], 0, bufferSize, true, true);
            ms.Write(byteType, 0, byteType.Length);
            ms.Write(Encoding.ASCII.GetBytes(data), 0, Encoding.ASCII.GetBytes(data).Length);

            byte[] byteData = ms.GetBuffer(); 

            sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), sock);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                int bytesSent = handler.EndSend(ar);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
        public void closeSocket()
        {
            try
            {
                if (sock.Connected)
                {
                    sock.Close();
                }
            }
            catch { }
        }

        public Socket getSocket()
        {
            return sock;
        }
    }
}

有任何想法吗?

4

2 回答 2

2

在您的服务器中,您有一个班级buffer成员Network,但每个客户端都有多个执行路径同时发生。如果您尝试为所有客户端使用相同的缓冲区,您将遇到这些冲突。

我建议您不要使用共享缓冲区,而是为每条消息使用单独的缓冲区。

于 2013-06-10T19:00:52.677 回答
0

你的大块代码在这里:

        StringBuilder sb = new StringBuilder();
        byte[] byteData = new byte[bytesRead];
        byteData = buffer;
        byte[] readData = new byte[byteData.Length - 1];
        Buffer.BlockCopy(byteData, 1, readData, 0, readData.Length);
        sb.Append(Encoding.ASCII.GetString(readData));
        String data = sb.ToString();

可以简单地替换为:

        String data = Encoding.ASCII.GetString(buffer, 0, bytesRead);

至于您的问题,我在您发布的代码中看不到任何明显的内容。问题可能出在您的handleData()方法中。

于 2013-06-10T18:55:17.210 回答