2013-03-08 73 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