>

TCP를 사용하여 C # 서버에서 Java 서버로 json을 전달하려고하는데 문제는 Java 서버가 처음으로 빈 json을 수신하는 것 같습니다. 두 번째로 계속 작동합니다. 출력 아래를 참조하십시오. 어떤 아이디어 나 제안이라도 미리 감사드립니다.

출력 :

Starting server...
Waiting for a connection..
Connected!
Reading...
Received empty object
Received: 
Connected!
Reading...
Received: "Request:gethotellist"
Connected!
Reading...
Received: "Request:gethotellist"

다음은 json을 보내기위한 C # 코드 스 니펫입니다.

public void GetHotelList()
{
TcpClient clientSocket = new TcpClient();
clientSocket.Connect("127.0.0.1", 6767);
NetworkStream ns = clientSocket.GetStream();
string jsonRequest = "Request:gethotellist";
string jsonToSend = JsonConvert.SerializeObject(jsonRequest);
byte[] dataBytes = Encoding.UTF8.GetBytes(jsonToSend);
ns.Write(dataBytes, 0, dataBytes.Length);
ns.Close();
}

자바 서버 :

public class JHotelServer
{
public static void main(String[] args) throws IOException
{
  final int PORT = 6767;
  System.out.println("Starting server...");     
  @SuppressWarnings("resource")
  ServerSocket welcomeSocket = new ServerSocket(PORT);  
  System.out.println("Waiting for a connection..");
  while(true)
  {             
     try
     {
        Socket connectionSocket = welcomeSocket.accept();  
        System.out.println("Connected!");
        Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
        connectionThread.start();
     }
     catch(IOException ioe)
     {
        ioe.printStackTrace();
     }         
  }
}
}

그리고 여기에 Tcp Communication Manager가 있습니다 :

public class TcpConnectionManager implements Runnable
{   
private DataInputStream inFromDotNet;
public TcpConnectionManager(Socket socket) throws IOException
{
  inFromDotNet = new DataInputStream(socket.getInputStream());
}
@Override
public void run()
{
  try
  {               
     System.out.println("Reading...");
     byte[] rvdMsgByte = new byte[inFromDotNet.available()];
     // Collecting data into byte array
     for (int i = 0; i < rvdMsgByte.length; i++)
     {
         rvdMsgByte[i] = inFromDotNet.readByte();
     }
     if (rvdMsgByte.length == 0)
     {
        System.out.println("Received empty object");
     }
     // Converting collected data in byte array into String.
     String rvdMsgTxt = new String(rvdMsgByte);
     System.out.println("Received: " + rvdMsgTxt);       
  }
  catch(IOException ioe)
  {
     ioe.printStackTrace();
  }
}
}

  • 답변 # 1

    표시된 코드를 기반으로, 페이로드 패킷이 아직 도착하지 않은 경우 inFromDotNet.available() 로 인해 페이로드가 비어있을 것으로 예상됩니다.  0이됩니다.

    기본적으로 .available()  "현재 버퍼링 된 바이트가 있습니다"(아마도 동기화 읽기와 비동기 읽기 중에서 선택할 수 있음)를 제외하고는해당을 사용하여 콘텐츠 관련 내용을 결정해서는 안됩니다.

    여기에 일반적으로 사용되는 두 가지 접근법이 있습니다 :

    EOF를 사용하여 페이로드의 끝을 표시합니다. 즉, 소켓이 닫 혔고 모든 것이 읽혀 졌다고 말할 때까지읽습니다. 이것을 감지하는 방법은 특정 소켓 API에 따라 다릅니다 (예 : .NET에서는 Receive 일 때)  양수가 아닌 숫자를 반환합니다)

    어떤 종류의 기본 프레임 프로토콜 구현

    첫 번째 옵션은 소켓 당 하나의 메시지 만 보내면 관련이 있습니다. 소켓 당 여러 개의 메시지를 보내려면 두 번째 옵션은필요입니다. 기본 프레이밍 프로토콜은 "메시지가 개행 문자로 분리"되는 것처럼 간단 할 수 있지만 대부분의 경우 길이 접두사와 같은 이진 안전 프레이밍이 필요할 수 있습니다. 예를 들어, JSON에는 줄 바꿈이 포함될 수 있으며 이는 줄 끝으로 잘못 해석 될 수 있습니다.

    어쨌든 : 소켓을 사용하면 데이터가 여러 패킷으로 나뉘어지고 수신 버퍼 크기가 너무 작기 때문에 루프에서 항상 읽어야합니다. 따라서 일반적으로 EOF 또는 프레임 끝을 감지 할 때까지 모든 페이로드를 반복하고 버퍼링하고콘텐츠 처리를 시작합니다. 특히 멀티 바이트 문자가 여러 개의 "읽기"/ "수신"호출에 걸쳐있을 수 있기 때문에 모든 것이 다 있다는 것을 알 때까지는 일반적으로 텍스트를 디코딩하려고 시도해서는 안됩니다. 따라서 스테이트 풀 텍스트 디코더를 사용하지 않는 한 이러한 문자를 잘못 해독 할 수 있습니다.

    당신이보고있는 행동은 거의 모든 플랫폼과 언어에 공통적입니다. Java/C #에만 국한되지 않습니다.

  • 이전 npm - 원사 설치 | 경고 패턴이 동일한 대상에서 포장을 풀려고합니다
  • 다음 windows - 가상 시나리오 - 향후 머신 호환성을위한 python 독립형 실행 파일