2011-05-08 8 views
0

저는 학교용 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(); 
     } 
    } 

답변

0

귀하의 읽기 방법은 결함이 예상대로 작동하지 않습니다.

TCP는 스트림 기반이며 메시지 기반이 아닙니다. Read 다음 메시지 중 하나를 포함 할 수 있습니다에 :

  • 메시지
  • 반 메시지
  • Excactly 하나의 메시지
  • 1.5 메시지의 조그마한 weeny 부분은
  • 두 메시지

따라서 완전한 메시지가 도착했는지 확인하려면 몇 가지 방법을 사용해야합니다. 가장 일반적인 방법은 다음과 같습니다

  • 메시지의 길이를 포함하는 고정 길이 헤더를 추가 메시지
  • 의 끝을 나타내는

또한해야한다 (예를 빈 라인) 바닥 글 추가 .NET에 존재하는 명명 지침을 수용하고 camelCase로 메소드 이름을 중지하십시오. 코딩중인 자바가 아닙니다.)

관련 문제