Ошибка сокета C/C++ в Java

Я пытаюсь установить связь через сокет между сервером Java и клиентом C. Когда я отправляю текст с клиента на сервер, например «AAAAA», я получаю сообщение об ошибке ниже. Почему это не работает? Я могу запускать эти коды со сценариями C to C и java to 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();
        }
    }
}

С++ клиент:

#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");
} 

person Yavuz    schedule 08.03.2013    source источник


Ответы (2)


Вы используете ObjectInputStream и ObjectOutputStream, которые предназначены для java-объектов (они не могут принимать ничего другого). Вместо этого используйте другие InputStream, OutputStream и у вас не должно возникнуть этой проблемы. Например, мне нравится использовать BufferedReader (хотя вы должны убедиться, что кодировка одинакова), как таковая:

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
person ddmps    schedule 08.03.2013
comment
Обязательно создайте InputStreamReader, набор символов которого соответствует локали и кодировке символов, используемой программой C; если вы этого не сделаете, символы, отличные от ASCII, не будут правильно прочитаны. - person VGR; 08.03.2013

Вы видите эту ошибку, потому что ObjectInputStream ожидает, что поступающие данные будут сериализованы определенным образом. В коде C++ вы просто отправляете необработанные данные.

Если вы просто хотите передать данные char, то это должны сделать InputStream и OutputStream, но если вы хотите передать более структурированные данные, это будет сложнее.

Я использовал DataInputStream и DataOutputStream для int, char и string, но это не было весело, и у вас есть сеть, упорядочивая проблемы, которые нужно решать, и она не будет переносимой. Вот предыдущий thread, который показывает хороший пример этого.

Если вам нужно что-то более сложное или что-то, что вы собираетесь поддерживать в производственной среде, вам, вероятно, следует изучить использование 0MQ или что-то подобное. Вот примеры Java и примеры C++.

person Shafik Yaghmour    schedule 08.03.2013
comment
Итак, есть ли что-то еще, что можно заменить ObjectInputStream или решением этой проблемы? - person Yavuz; 08.03.2013
comment
@Yavuz Да, я добавил несколько альтернатив. - person Shafik Yaghmour; 08.03.2013