是否可以使用 Unix 套接字在 C 应用程序和 Java 应用程序之间创建通信?

Posted

技术标签:

【中文标题】是否可以使用 Unix 套接字在 C 应用程序和 Java 应用程序之间创建通信?【英文标题】:Is it possible to create a communication between C application and Java application using Unix Sockets? 【发布时间】:2017-04-12 03:33:48 【问题描述】:

我有一个写在 C: 上的服务器应用程序:

int main(int argc, char const *argv[]) 

int sock;

struct sockaddr_un serv_addr;

size_t serv_addr_len;

int msgsock;
char buf[1024];
int msg_len;

remove(SOCKET_ADDRESS);

sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);

if (sock < 0) 
    perror("Opening stream socket");
    exit(1);


memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sun_family = AF_UNIX;

strcpy(serv_addr.sun_path, SOCKET_ADDRESS);

serv_addr_len = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);

if (bind(sock, (struct sockaddr *) &serv_addr, serv_addr_len)) 
    perror("Binding stream socket");
    exit(1);


if (listen(sock, 5) < 0) 
    perror("Listening falied");
    exit(1);


while (TRUE) 
    msgsock = accept(sock, (struct sockaddr *) 0, 0);

    if (msgsock == -1) 
        perror("Accept");
    
    else 
        do 
            memset(buf, 0, sizeof(buf));

            if ((msg_len = recv(msgsock, buf, sizeof(buf), MSG_WAITALL)) < 0) 
                perror("Reading stream message");
            
            else if (msg_len == 0) 
                printf("Ending connection\n");
            
            else 
                printf("%s\n", buf);
            
         while (msg_len > 0);

        close(msgsock);
    

return 0;

并让一个客户使用 junixsocket lib 在 Java 上编写代码:

package client;

import java.io.*;
import org.newsclub.net.unix.AFUNIXSocket;
import org.newsclub.net.unix.AFUNIXSocketAddress;

public class Client 

public static void main(String args[]) 

    final String socketAddress = "/home/andrew/IdeaProjects/Sample/tmp/SOCKET_ADDRESS";

    String message = "Hello Server!";

    try 
        final File socketFile = new File(socketAddress);

        AFUNIXSocket socket = AFUNIXSocket.newInstance();

        socket.connect(new AFUNIXSocketAddress(socketFile));

        OutputStream out = socket.getOutputStream();

        out.write(message.getBytes());
        out.flush();
        socket.close();
    
    catch (IOException e) 
        e.printStackTrace();
    


我启动了服务器,并尝试连接,然后得到异常:

/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java -Didea.launcher.port=7533 -Didea.launcher.bin.path=/home/andrew/Downloads/idea-IU-163.7743.44/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk- amd64/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-1.8。 0-openjdk-amd64/jre/lib/ext/icedtea-sound.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/jaccess.jar:/usr/lib/ jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/nashorn.jar:/ usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunjce_provider .jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib /ext/zipfs.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre /lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/management-agent.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64 /jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/ jre/lib/rt.jar:/home/andrew/IdeaProjects/Sample/out/production/Sample:/home/andrew/Workspace/libs/junixsocket-1.3.jar:/home/andrew/Workspace/libs/junixsocket-demo -1.3.jar:/home/andrew/Workspace/libs/junixsocket-mysql-1.3.jar:/home/andrew/Workspace/libs/junixsocket-rmi-1.3.jar:/home/andrew/Downloads/idea-IU- 163.7743.44/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain client.Client org.newsclub.net.unix.AFUNIXSocketException:协议类型错误 套接字(套接字:/home/andrew/IdeaProjects/Sample/tmp/SOCKET_ADDRESS) 在 org.newsclub.net.unix.NativeUnixSocket.connect(Native Method) 在 org.newsclub.net.unix.AFUNIXSocketImpl.connect(AFUNIXSocketImpl.java:125) 在 org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:97) 在 org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:87) 在 client.Client.main(Client.java:19) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

请帮帮我!

【问题讨论】:

Java 和 C 程序应该能够通信,因为它们都使用套接字。您得到的具体错误似乎是这部分“AFUNIXSocketException: Protocol wrong type for socket” 【参考方案1】:

unix 域套接字是一种特定于平台的机制,没有本地库的 java 不支持它。您使用org.newsclub.net.unix.AFUNIXSocket。但是这个库只支持套接字类型SOCK_STREAMSOCK_DGRAM。您的 C 应用程序使用 SOCK_SEQPACKET,它是该库不支持的 unix 域套接字的特定于 linux 的扩展。

【讨论】:

以上是关于是否可以使用 Unix 套接字在 C 应用程序和 Java 应用程序之间创建通信?的主要内容,如果未能解决你的问题,请参考以下文章

使用 C TCP 套接字,“发送”可以返回零吗?

使用 node-ipc 和 unix 套接字在 C 和 NodeJS 之间进行通信

在 Unix 上使用套接字在 C 中发送和接收文件(服务器/客户端)

Unix 域套接字和 NPAPI

TCP 环回连接与 Unix 域套接字性能

D-Bus 可以在不是 Unix 域套接字的流上使用吗?