0

我正在尝试在 Java 服务器和 C 客户端之间进行套接字通信。当我从客户端向服务器发送文本时,例如“AAAAA”,我在下面出现错误。为什么它不起作用?我可以使用 C 到 C 和 java 到 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");
} 
4

2 回答 2

2

您正在使用ObjectInputStreamand ObjectOutputStream,它们是为 java 对象设计的(它们不能接受其他任何东西)。相反,使用另一个InputStreamOutputStream你不应该得到这个问题。例如我喜欢使用BufferedReader(你必须确保编码是相等的),例如:

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
于 2013-03-08T13:27:16.630 回答
1

您看到该错误是因为ObjectInputStream期望传入的数据以特定方式序列化。在 C++ 代码中,您只是发送原始数据。

如果您只想传递 char 数据而不是InputStream应该OutputStream这样做,但是如果您想传递更多结构化数据,那将更加棘手。

我用过DataInputStreamDataOutputStream,但它并不好玩intchar而且string你可以通过订购问题来处理网络,而且它不会是可移植的。这是一个以前的线程,它展示了一个很好的例子。

如果您想要更复杂的东西或要在生产环境中支持的东西,那么您可能想要考虑使用0MQ或类似的东西。这里是Java 示例,这里是C++ 示例

于 2013-03-08T13:23:36.163 回答