2011-05-08 73 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;)

相關問題