Приложение останавливается при получении информации через сокет - PullRequest
0 голосов
/ 08 мая 2011

Я работаю над клиентским серверным приложением C # для школы, и у меня возникла небольшая проблема.Когда я вхожу с правами администратора в мое приложение, все работает нормально, информация проходит через сокет, но когда мне нужно получить ClientsList через сокет, в форме администратора говорится «Не отвечает», и больше ничего не происходит.

Может кто-нибудь сказать мне, почему при входе в систему работает, а после этого он больше не работает?Спасибо

вот некоторые части моего проекта:

Входная часть, она отлично работает:

 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, она не работает:

  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:

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

Класс сервера:

  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:

 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 Ответ

0 голосов
/ 09 мая 2011

Ваш метод чтения некорректен и не будет работать должным образом.

TCP основан на потоке, а не на сообщениях.На Read может содержать любое из следующих сообщений:

  • Небольшая часть сообщения
  • Половина сообщения
  • Точно одно сообщение
  • Полтора сообщения
  • Два сообщения

Таким образом, вам нужно использовать какой-то метод, чтобы увидеть, пришло ли полное сообщение.Наиболее распространенные методы:

  • Добавление нижнего колонтитула (например, пустой строки), указывающего конец сообщения
  • Добавление заголовка фиксированной длины, содержащего длину сообщения

Вы также должны принять правила именования, которые существуют для .NET, и остановитесь на camelCase для имен методов.Вы пишете не на Java;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...