Application stops when receiving info through socket

こ雲淡風輕ζ 提交于 2019-12-13 21:17:01

问题


I'm working on my C# client server application for school, and I have a tiny little problem. When I login with the admin in my application, everything works fine, the information passes through the socket, but when I need to get the ClientsList through the socket, on the administrator form say Not Responding, and nothing else happens.

Can anyone tell me why at the login works, and after that it doesn't work anymore? Thanks

here are some parts of my project:

The login part, it works fine:

 private void btnLogin_Click(object sender, EventArgs e)
        {
            String user = txtUser.Text;
            String pass = txtPass.Text;

            ClientConnectionHandler handler = ClientConnectionHandler.getInstance();
            handler.sendMessage("#login#" + user + " " + pass + "#");
            User u = (User) handler.receive();



            if (u == null)
            {
                MessageBox.Show("Username/Password is wrong");
            }
            else
            {
                if (u.getRang().Equals("admin"))
                {

                    (new AdminWin(u)).Show();
                    this.Hide();
                }
                else{
                    (new ClientWin(u)).Show();
                    this.Hide();
                }
            }
            handler.kill();

        }

The getClientList part, it does not work:

  public partial class AdminWin : Form
    {
        private User user;

        public AdminWin(User u)
        {
            user = u;
            InitializeComponent();

            ClientConnectionHandler handler = ClientConnectionHandler.getInstance();
            handler.sendMessage("#getClientList# #");

            handler.receive();

            //listUsers.DataSource = users;

        }


    }

The ClientConnectionHandler:

 public class ClientConnectionHandler
    {
        private static ClientConnectionHandler INSTANCE;
        private static Socket socket;

        private ClientConnectionHandler()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
            socket.Connect("127.0.0.1", 1234);
        }

        public static ClientConnectionHandler getInstance()
        {
            if (INSTANCE == null)
                INSTANCE = new ClientConnectionHandler();
            return INSTANCE;
        }

        public void sendMessage(String message)
        {
            byte[] buffer = new byte[1024];
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream(buffer);

            formatter.Serialize(stream, message);
            stream.Flush();
            socket.Send(buffer, buffer.Length, 0);
        }

        public Object receive()
        {
            byte[] buffer = new byte[10240];
            socket.Receive(buffer);
            return toObject(buffer);
        }

        private Object toObject(byte[] byteArray)
        {
            MemoryStream memStream = new MemoryStream();
            BinaryFormatter binForm = new BinaryFormatter();
            memStream.Write(byteArray, 0, byteArray.Length);
            memStream.Seek(0, SeekOrigin.Begin);
            Object obj = (Object)binForm.Deserialize(memStream);
            return obj;
        }

        public void kill()
        {
            socket.Close();
        }
    }

The Server class:

  class Server
    {
        public static void Main()
        {
            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1234);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            socket.Bind(ipEndPoint);
            socket.Listen(100);
            Console.WriteLine("Server Started");

            while (true)
            {
                Socket clientSocket = socket.Accept();
                clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                Thread clientThread = new Thread(new ThreadStart(new ServerConnectionHandler(clientSocket).handle));
                clientThread.Start();
            }
        }

    }

And the ServerConnectionHandler:

 class ServerConnectionHandler
    {
        private Socket socket;

        public ServerConnectionHandler(Socket socket)
        {
            this.socket = socket;
        }

        public void handle()
        {
            byte[] data = new byte[1024];
            int receivedDataLength = socket.Receive(data);
            String stringData = new ASCIIEncoding().GetString(data);

            stringData = stringData.Substring(stringData.IndexOf("#"));

            Console.WriteLine(stringData);

            string[] bySharp = stringData.Split('#');

            string action = bySharp[1];
            string info = bySharp[2];

            Console.WriteLine(action + " " + info);

            switch (action)
            {
                case "login": handleLogin(info); break;
                case "getClientList": handleClientList(); break;
                case "getCDsForClient": handleCDList(info); break;
                case "addCDForClient": handleAdd(info); break;
                case "remCD": handleRem(info); break;
                case "modCD": handleMod(info); break;
            }
        }

        private void handleLogin(string info)
        {
            string[] bySpace = info.Split(' ');
            string user = bySpace[0];
            string pass = bySpace[1];

            User u = RepositoryManager.getInstance().getUser(user, pass);

            sendToClient(toByteArray(u));
        }

        private void handleClientList()
        {
            sendToClient(toByteArray(RepositoryManager.getInstance().getClientList()));
        }

        private void handleCDList(string info)
        {
            long userId = long.Parse(info);
            sendToClient(toByteArray(RepositoryManager.getInstance().getCDs(userId)));
        }

        private void handleAdd(string info)
        {
            string[] byTilda = info.Split('~');

            long userId = long.Parse(byTilda[0]);
            String cdName = byTilda[1];
            String cdType = byTilda[2];
            RepositoryManager.getInstance().addCD(userId, cdName,
                cdType);
        }

        private void handleRem(string info)
        {
            string[] bySpace = info.Split(' ');
            long userId = long.Parse(bySpace[0]);
            long cdId = long.Parse(bySpace[1]);
            RepositoryManager.getInstance().remCD(userId, cdId);
        }

        private void handleMod(string info)
        {
            string[] byTilda = info.Split('~');
            long userId = long.Parse(byTilda[0]);
            long cdId = long.Parse(byTilda[1]);
            String newName = byTilda[2];
            String newType = byTilda[3];

            RepositoryManager.getInstance().modCD(userId, cdId,
                newName, newType);
        }

        private void sendToClient(byte[] info)
        {
            socket.Send(info, info.Length, 0);
        }

        private byte[] toByteArray(Object o)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, o);
            return ms.ToArray();
        }
    }

回答1:


Your Read method is flawed and will not work as expected.

TCP is stream based and not message based. On Read can contain any of the following messages:

  • A teeny weeny part of message
  • A half message
  • Excactly one message
  • One and a half message
  • Two messages

Thus you need to use some kind of method to see if a complete message have arrived. The most common methods are:

  • Add a footer (for instance an empty line) which indicates end of message
  • Add a fixed length header containing the length of the message

You should also embrace the naming guidelines which exist for .NET and stop with the camelCase for method names. It's not Java you are coding ;)



来源:https://stackoverflow.com/questions/5929575/application-stops-when-receiving-info-through-socket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!