2012-02-26 2 views
0

저는 C# 클라이언트에서 Java 서버로 프로그램 코드 파일을 보내도록 설계된 파일 업 로더를 작성했습니다. 서버는 파일 업로드를 수락하기 전에 유효한 사용자 이름과 암호를 제출해야합니다.동일한 네트워크 스트림 및 소켓 연결을 사용하여 C# 클라이언트에서 Java 서버로 다중 바이트 []를 보낼 때 Hanging

보안 (사용자 이름과 암호)과 파일 업 로더가 각각 올바르게 작동합니다. 그러나 두 가지를 결합하려고하면 C# 클라이언트에서 진정한 부울 응답을받은 후 올바른 사용자 이름과 암호를 나타내는 서버에서 코드가 멈 춥니 다. 클라이언트와 서버의 관련 코드가 첨부됩니다.

C#을 클라이언트

public static string sendValidatedFile(string username, string password, string path) { 

     string inputString = "NotSent"; 

     try { 

      TcpClient client = new TcpClient("127.0.0.1", 42000); 

      StreamReader input = new StreamReader(stream); 

      Stream securityStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(username + "_" + password + "_\n")); 

      byte[] bufferA = new byte[securityStream.Length]; 
      securityStream.Read(bufferA, 0, bufferA.Length); 

      stream.Write(bufferA, 0, bufferA.Length); 
      stream.Flush(); 

      inputString = input.ReadToEnd(); 
      bool result = bool.Parse(inputString); 

      if (result) { 

       print("Login Accepted"); 

       Stream fileStream = File.OpenRead(path); 

       byte[] buffer = new byte[fileStream.Length]; 
       fileStream.Read(buffer, 0, buffer.Length); 

       // This is where the code seems to lock up 
       stream.Write(buffer, 0, buffer.Length); 
       stream.Flush(); 

       inputString = input.ReadToEnd(); 

      } 

      else { 

       inputString = "Invalid Username or Password"; 

      } 

      input.Close(); 
      stream.Close(); 
      client.Close(); 

     } 

     catch (SocketException e) { 

      print("Error" + e); 

     } 

     catch (IOException e) { 

      print("Error" + e); 

     } 

     return inputString; 

    } 

자바 서버

public void run() { 

try { 

    // Get username and password 
    byte[] byteArrayJAR = new byte[filesize]; 
    byte[] byteArraySecurity = new byte[filesize]; 
    InputStream input = socket.getInputStream(); 
    PrintWriter output = new PrintWriter(socket.getOutputStream()); 

    int bytesSecurity = input.read(byteArraySecurity, 0, byteArraySecurity.length); 
    int currentByte1 = bytesSecurity; 

    if (input.available() > 0) { 

     do { 

      bytesSecurity = input.read(
        byteArraySecurity, 
        currentByte1, 
        (byteArraySecurity.length - currentByte1)); 

      if (bytesSecurity >= 0) { 

       currentByte1 += bytesSecurity; 

      } 
     } 

     while (bytesSecurity > -1); 
    } 

    String securityString = new String(byteArraySecurity).trim(); 
    String[] authenticationString = securityString.split("_"); 
    String username = authenticationString[0]; 
    String password = authenticationString[1]; 

    // Validate the username and password with a stored database 
    if (security.validateUser(username, password)) { 

     // Inforn the client their username and password were accepted 
     output.println(true); 
     output.flush(); 

     // Get the program code file 
     int bytesRead = input.read(byteArrayJAR, 0, byteArrayJAR.length); 
     int currentByte = bytesRead; 

     if (input.available() > 0) { 

       do { 

        bytesRead = input.read(
        byteArrayJAR, 
          currentByte, 
          (byteArrayJAR.length - currentByte)); 

       if (bytesRead >= 0) { 

         currentByte += bytesRead; 

        } 
      } 

       while (bytesRead > -1); 

    } 

     // Inform the client that the code was received 
     output.println("Success"); 
     output.flush(); 

    } 

    else { 

     // Inform the client their username or password was incorrect 
     output.println(false); 
     output.flush(); 

    } 

    // Disconnect from client 
    output.flush(); 
    output.close(); 
    input.close(); 
    socket.close(); 

} 

catch (IOException e) { 

    e.printStackTrace(); 

} 

}

아무도 그 위의 내 코드가 정지 원인이 될 수 잘못 아무것도 볼 수 있습니까? C# 클라이언트가 두 인스턴스에서 모두 전송할 데이터가 있어야합니다. 두 바이트 배열을 C#에서 동일한 네트워크 스트림에서 보낼 수없는 이유가 있습니까?

나는 위의 코드를 교수형없이 작업 할 수있는 도움을 주시면 감사하겠습니다.

안부,

Midavi.

+1

C# 코드에서 "사용"을 고려하십시오. 이러한 객체의 대부분은 IDisposable이며 예상치 못한 일이 발생하면 대부분의 객체가 올바르게 처리되지 않습니다. –

답변

0

input.ReadToEnd()를 두 번 사용하고 있습니다. 스트림에는 한쪽 끝만 있습니다. 나는 이것들 중 첫 번째가 부적절한 것으로 의심하고 더 직접적인 독서로, 아니면 기껏해야 ReadLine으로 대체해야한다.

여기서 대화가 클라이언트와 서버 사이의 여러 메시지에 의존하는 경우 메시지 중 하나가 아직 버퍼링되어 있고 실제로 전송되지 않았기 때문에 nagle이 활성화되어 있는지 확인할 수 있습니다 (플러시) 네트워크 스트림에 아무 것도하지 않습니다.) - 소켓에 대해 NoDelay (또는 동급)를 설정해야 할 수도 있습니다. 기본 동작은 작은 패킷을 많이 버퍼링하여 네트워크에 대량의 패킷이 넘치는 것을 방지하는 것입니다.

+0

조언 해 주셔서 감사합니다. 나는 당신의 팁을 시도하고 다시보고 할 것입니다. – midavi

+0

잘 찾아 냈습니다. 문제는 첫 번째 input.ReadToEnd()입니다. 나는 그것을 input.ReadLine()으로 변경했다. 이제 모든 것이 잘 작동합니다. 용감히 나는 독수리를 가지고 다니지 않아도되었다. 당신의 도움을 주셔서 감사합니다. – midavi