2013-03-08 2 views
0

Java 서버와 C 클라이언트간에 소켓 통신을 시도하고 있습니다. 예를 들어 "AAAAA"와 같이 클라이언트에서 서버로 텍스트를 보내면 아래 오류가 발생합니다. 왜 작동하지 않는거야? C에서 C로, Java에서 Java로 이러한 코드를 실행할 수 있습니다.C/C++ to Java Socket 오류

Waiting for connection 
Connection received from 127.0.0.1 
java.io.StreamCorruptedException: invalid stream header: 41414141 
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source) 
    at java.io.ObjectInputStream.<init>(Unknown Source) 
    at Provider.run(Provider.java:22) 
    at Provider.main(Provider.java:67) 
Exception in thread "main" java.lang.NullPointerException 
    at Provider.run(Provider.java:43) 
    at Provider.main(Provider.java:67) 

자바 서버 :

import java.io.*; 
import java.net.*; 
public class Provider{ 
    ServerSocket providerSocket; 
    Socket connection = null; 
    ObjectOutputStream out; 
    ObjectInputStream in; 
    String message; 
    Provider(){} 
    void run() 
    { 
     try{ 
      //1. creating a server socket 
      providerSocket = new ServerSocket(2004, 10); 
      //2. Wait for connection 
      System.out.println("Waiting for connection"); 
      connection = providerSocket.accept(); 
      System.out.println("Connection received from " + connection.getInetAddress().getHostName()); 
      //3. get Input and Output streams 
      out = new ObjectOutputStream(connection.getOutputStream()); 
      out.flush(); 
      in = new ObjectInputStream(connection.getInputStream()); 
      sendMessage("Connection successful"); 
      //4. The two parts communicate via the input and output streams 
      do{ 
       try{ 
        message = (String)in.readObject(); 
        System.out.println("client>" + message); 
        if (message.equals("bye")) 
         sendMessage("bye"); 
       } 
       catch(ClassNotFoundException classnot){ 
        System.err.println("Data received in unknown format"); 
       } 
      }while(!message.equals("bye")); 
     } 
     catch(IOException ioException){ 
      ioException.printStackTrace(); 
     } 
     finally{ 
      //4: Closing connection 
      try{ 
       in.close(); 
       out.close(); 
       providerSocket.close(); 
      } 
      catch(IOException ioException){ 
       ioException.printStackTrace(); 
      } 
     } 
    } 
    void sendMessage(String msg) 
    { 
     try{ 
      out.writeObject(msg); 
      out.flush(); 
      System.out.println("server>" + msg); 
     } 
     catch(IOException ioException){ 
      ioException.printStackTrace(); 
     } 
    } 
    public static void main(String args[]) 
    { 
     Providerserver = new Provider(); 
     while(true){ 
      server.run(); 
     } 
    } 
} 

C++ 클라이언트 : ObjectInputStream이 들어오는 데이터를 특정 방법으로 직렬화 할 것으로 예상하기 때문에

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <conio.h> 
#include <winsock2.h> 

#define PORTNO  2004 

void ExitSys(); 

int main(void) 
{ 
    WSADATA wsd; 
    int result; 
    SOCKET clientSocket; 
    struct sockaddr_in sinServer; 
    struct hostent *host; 
    char serverHost[] = "localhost"; 

    if ((result = WSAStartup(MAKEWORD(2, 2), &wsd)) != 0) 
     ExitSys(); 

    if ((clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) 
     ExitSys(); 

    sinServer.sin_family = AF_INET; 
    sinServer.sin_port = htons(PORTNO); 
    sinServer.sin_addr.s_addr = inet_addr(serverHost); 
    if (sinServer.sin_addr.s_addr == INADDR_NONE) { 
     host = gethostbyname(serverHost); 
     if (host == NULL) 
      ExitSys(); 
     memcpy(&sinServer.sin_addr.s_addr, host->h_addr_list[0], host->h_length); 
    } 

    if (connect(clientSocket, (struct sockaddr *) &sinServer, sizeof(sinServer)) == SOCKET_ERROR) 
     ExitSys(); 

    printf("connected...\n"); 

    for (;;) { 
     char buf[512]; 
     printf("Text:"); 
     gets(buf); 
     if (!strcmp(buf, "quit")) 
      break; 
     if (send(clientSocket, buf, strlen(buf), 0) == SOCKET_ERROR) 
      ExitSys(); 
    } 

    shutdown(clientSocket, SD_BOTH); 
    closesocket(clientSocket); 

    WSACleanup(); 

    return 0; 
} 

void ExitSys() 
{ 
    printf("extited"); 
} 

답변

2

자바 객체 용으로 설계된 및 ObjectOutputStream을 사용하고 있습니다. 다른 것들은 사용할 수 없습니다. 대신 다른 InputStream, OutputStream을 사용하면이 문제가 발생하지 않습니다. 예를 들어 나는 같은 BufferedReader을 (당신이 인코딩하지만 동일 확인해야합니다) 사용하려면 :

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); 
+1

Charset가 C 프로그램이 사용하는 로케일 및 문자 인코딩과 일치하는 InputStreamReader를 작성하십시오. 그렇지 않으면 비 ASCII 문자가 올바르게 읽히지 않습니다. – VGR

1

당신은 그 오류를보고있다. C++ 코드에서는 원시 데이터를 보내고 있습니다.

InputStreamOutputStream보다 char 데이터를 전달하려는 경우 더 많은 구조화 된 데이터를 전달하려는 경우보다 더 까다로울 것입니다.

나는 int, charstring에 대한 DataInputStreamDataOutputStream을 사용했지만 재미 아니었고 당신이 다루는 문제를 주문하여 네트워크를 가지고 있으며 휴대용 될 수 없습니다. 이전의 thread은 좋은 예입니다.

더 세련된 것이나 프로덕션 환경에서 지원하려는 것을 원하는 경우 0MQ 또는 유사한 것을 사용하려고합니다. 여기에 Java examples이고 여기에 C++ examples입니다.

+0

그래서 ObjectInputStream에 또는 그 문제에 대한 솔루션을 대체 할 또 다른 점은 무엇입니까? – Yavuz

+0

@Yavuz 예, 몇 가지 대안을 추가했습니다. –