2011-05-08 72 views
0

我正在为我的学校开发C#客户端服务器应用程序,并且遇到了一个小问题。当我在应用程序中使用管理员登录时,一切正常,信息通过套接字传递,但是当我需要通过套接字获取ClientsList时,管理员表单上显示Not Responding,并且没有其他事情发生。通过套接字接收信息时,应用程序停止

任何人都可以告诉我为什么在登录作品,之后它不再工作?由于

这里是我的项目的一些部分:

登录部分,它工作正常:

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

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:

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

回答

0

你读的方法是有缺陷的,因为将无法正常工作。

TCP是基于流而不是基于消息的。上Read可以含有任何以下消息之一:

  • 消息
  • 半消息
  • Excactly一个消息
  • 一个半消息的蝇头纤细部分
  • 两个消息

因此,您需要使用某种方法来查看是否有完整的消息到达。最常见的方法是:

  • 添加页脚(例如一个空行),其指示消息
  • 的末尾添加包含该消息的长度的固定长度的首部

还应该包含.NET存在的命名准则,并停止使用camelCase作为方法名称。这不是你正在编码的Java;)

相关问题