2012-06-28 2 views
2

우선, 저는 네트워크 프로그래머가 아닙니다. 내가하려고하는 것은 Java 서버와 C# 클라이언트 간의 매우 간단한 TCP/IP 통신입니다.불완전한 메시지 (C# TCP/IP 클라이언트)

자바 서버 :

public class ComInterface : MonoBehaviour 
    { 
     public const String SERVER_IP = "127.0.0.1"; // Localhost 
     public const int PORT = 1100; // Default port 
     public const int READ_BUFFER_SIZE = 5000; // 4.8828125 kilobytes 

     private TcpClient _client; 
     private ASCIIEncoding _asen; 
     private byte[] _readBuffer; 
     private String _msg; 

     public Boolean connected { get; internal set; } // setter is for internal use only 

     /** 
     * Initialize internal variables (buffer, socket...) 
     */ 
     public ComInterface() 
     { 
      connected = false; 
      _client = new TcpClient(); 
      _asen = new ASCIIEncoding(); 
      _readBuffer = new Byte[READ_BUFFER_SIZE]; 
      _msg = String.Empty; 
     } 

     /** 
     * Connect to server at SERVER_IP:PORT 
     * Return true if connection was a success, or false if failure. 
     */ 
     public Boolean Connect() 
     { 
      try 
      { 

       _client.Connect(SERVER_IP, PORT); 
       connected = true; 
       Array.Clear(_readBuffer, 0, _readBuffer.Length); 
       Debug.Log("TCPClient: <Connect> Connected to the server"); 
       // Start an asynchronous read invoking ReceiveComMessage 
       _client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _client.GetStream()); 
      } 
      catch (Exception ex) 
      { 
       Debug.Log("TCPClient: <Connect> Cannot connect to the server - " + ex.Message); 
       connected = false; 
      } 
      // Return connection state 
      return connected; 
     } 

/** 
     * Received a message from Communicator 
     */ 
     private void ReceiveComMessage(IAsyncResult ar) 
     { 
      int BytesRead; 
      String msg; 
      try 
      { 
       BytesRead = _client.GetStream().EndRead(ar); 
       if (BytesRead < 1) 
       { 
        // if no bytes were read server has close. 
        Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (BytesRead<1)"); 
        this.Disconnect(); 
        return; 
       } 
       // Convert the byte array the message was saved into, 
       msg = Encoding.ASCII.GetString(_readBuffer); 
       Debug.Log("C# Message: \"" + msg + "\""); // Output example in log below 
       BytesRead = 0; 
       Array.Clear(_readBuffer, 0, _readBuffer.Length); 

       // Start a new asynchronous read into readBuffer. 
       _client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _readBuffer); 

      } 
      catch (Exception ex) 
      { 
       Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (Exception):" + ex.Message + " see " + ex.StackTrace); 
       this.Disconnect(); 
      } 

가장 큰 문제는 모든 메시지가 불완전한 도착하는 것입니다 : 여기

public void run(){ 
try { 
     // Open server socket 
     _server = new ServerSocket(SERVER_PORT); 
     _client = _server.accept(); 
       System.out.println("ComInterface: client connected."); 
       // Wait for a client data output stream 
       while(true){ 

        // Receive message from client 
        BufferedReader is = 
          new BufferedReader(new InputStreamReader(_client.getInputStream())); 
        msg = is.readLine(); 

        // Process message 
        if(msg!=null){ 
         System.out.println("ComInterface: Message Received : <" + msg + ">."); 
         processMessage(msg); // Independant method 
        } 
        else{ 
         System.out.println("ComInterface: client closed connection."); 
         _client.close(); 
         _client = _server.accept(); 
         System.out.println("ComInterface: client connected."); 
        } 

       } 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
} 

public void sendMessage(String msg){ 
     try { 

      // Out stream 
      DataOutputStream os = new DataOutputStream(_client.getOutputStream()); 

      os.writeBytes((String)(msg+"\n"+(char)13)); 
      os.flush(); 
      System.out.println("ComInterface: Message <" + msg + "> sent"); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

그리고는 C# 클라이언트입니다.

C#: Message "{ 
C#: Message ""sender":"Bob"", 
C#: Message ""recipient":", 
etc... 

대신 인스턴스

C#: Message "{"sender":"Bob","recipient":[1,2,3]}" 

에 대한

내가 조금 혼란 스러워요 나는이 문제를 해결하는 데 도움이 필요할 것 : 여기 로그 추적입니다. 고마워요!

답변

2

TCP은 메시지 지향이 아닌 스트림 지향 연결입니다. 메시지에 대한 개념이 없습니다. 직렬화 된 문자열을 쓸 때 의미없는 바이트 시퀀스 만 보입니다. TCP는 스트림을 여러 조각으로 나누어서 조각 크기의 청크로 클라이언트에서 수신합니다. 다른 쪽 끝에서 전체 메시지를 재구성하는 것은 당신에게 달려 있습니다.

시나리오에서 일반적으로 메시지 길이 접두어를 보냅니다. 이렇게하면 클라이언트는 처음에는 길이 접두어를 읽고 들어오는 메시지의 크기를 알 수 있습니다.

메시지를 신고하고 크기 접두어 옵션으로 스트리밍하는 좋은 방법으로 Google Protocol Buffers을 사용하는 것을 진지하게 고려할 것입니다. 좋은 점은 메시지 세트를 한 번 정의한 다음 사용 가능한 tools을 사용하여 메시지 정의에서 C++, Java, C# 등의 코드를 자동으로 생성하는 것입니다. 이렇게하면 언어간에 작동하는 일관된 메시징 세트가 있어야 도움이됩니다.

1

메시지 (모든 데이터)는 소켓을 통해 전송 될 때 개의 패킷으로 나뉩니다. 받은 각 패킷을 인쇄 할 때 전체 메시지가 표시되지 않습니다.

메시지 문자열 끝 부분에 문자열 (예 : ". #.")을 정의해야합니다. 이 순서를받을 때까지받은 메시지를 연결합니다.

이것은 무엇입니까 세션 프로토콜 (즉, TCP의 상단에서 실행되는 프로토콜)은 무엇입니까?

희망이 도움이됩니다.

감사합니다, Calil

0

이 예를 살펴 보자 ...

자바 TCP 서버 ...

import java.net.*; 
import java.io.*; 

public class TcpServer 
{ 
    public static void main(String h[]) 
    { 
     try 
     { 
      ServerSocket serverSocket = new ServerSocket(1100); 
      Socket socket = serverSocket.accept(); 
      System.out.println("Client Accepted"); 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      System.out.println("Received: " + bufferedReader.readLine()); 
      PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); 
      printWriter.println("Hello Theo. Welcome to socket programming."); 
     } catch (Exception e) 
     { 
      System.out.println(e); 
     } 
    } 
} 

C#의 TCP 클라이언트 ...

using System; 
using System.IO; 
using System.Net.Sockets; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      var client = new TcpClient("localhost", 1100); 
      var stream = client.GetStream(); 
      var streamWriter = new StreamWriter(stream); 
      streamWriter.WriteLine("My name is Theo"); 
      streamWriter.Flush(); 
      var streamReader = new StreamReader(stream); 
      Console.WriteLine("Received: " + streamReader.ReadLine()); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
     } 

     Console.WriteLine("Press a key to continue."); 
     Console.ReadKey(); 
    } 
} 
관련 문제