通过套接字接收信息时应用程序停止 [英] Application stops when receiving info through socket

查看:127
本文介绍了通过套接字接收信息时应用程序停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习我的C#客户端服务器应用程序,我有一个小小的问题。当我在我的应用程序中使用管理员登录时,一切正常,信息传递通过套接字,但是当我需要通过套接字获得ClientsList,在管理员形式说不响应,没有其他发生。

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();

        }

getClientList部分,它不工作:

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;

        }


    }

ClientConnectionHandler:

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();
        }
    }

Server类别:

  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();
            }
        }

    }

ServerConnectionHandler:

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();
        }
    }


推荐答案

读取方法有缺陷,将无法正常工作。

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

TCP是基于流的,不是基于消息的。在上阅读可以包含以下任何消息:

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



  • 一封半封邮件

  • 一封邮件
  • b $ b
  • 两个邮件

  • 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:


  • 添加表示邮件结束的页脚(例如空行)

  • 添加包含消息长度的固定长度标头

您还应该接受.NET中存在的命名准则并使用camelCase停止方法名称。它不是你编码的Java;)

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 ;)

这篇关于通过套接字接收信息时应用程序停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆