2013-03-08 70 views
0

我試圖在Java服務器和C客戶端之間進行套接字通信。當我從客戶端發送文本到服務器,例如「AAAAA」,我在下面寫錯。爲什麼它不起作用?我可以使用C到C和java到java場景運行這些代碼。C/C++到Java套接字錯誤

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) 

Java服務器:

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++客戶端:

#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

您正在使用ObjectInputStreamObjectOutputStream,這是專爲java對象(他們不能採取任何其他)。相反,使用另一個InputStream,OutputStream,你不應該得到這個問題。比如我喜歡用BufferedReader(你必須確保編碼是相等的,雖然),因爲這樣的:

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

確保創建一個InputStreamReader,它的Charset與C程序使用的語言環境和字符編碼相匹配;如果您不這樣做,則不會正確讀取非ASCII字符。 – VGR 2013-03-08 13:30:57

1

你所看到的這個錯誤,因爲ObjectInputStream預計未來在數據以一種特定的方式進行序列化。在C++代碼中,您只是發送原始數據。

如果你只是想傳遞char數據而不是InputStreamOutputStream應該這樣做,但如果你想傳遞更多的結構化數據比它更棘手。

我已經使用intcharstringDataInputStreamDataOutputStream但它不是樂趣,你通過訂購的問題來處理具有網絡和它不會是便攜。以前的thread就是一個很好的例子。

如果你想要更復雜的東西,或者你想在生產環境中支持的東西,那麼你可能想使用0MQ或類似的東西。這裏是Java examples,這裏是C++ examples

+0

那麼,有沒有另一件事與ObjectInputStream的或爲該問題的解決方案,以取代? – Yavuz 2013-03-08 13:27:22

+0

@Yavuz是的,我添加了一些替代品。 – 2013-03-08 13:38:07