通过JNI结合插座
我尝试通过JNI在Linux计算机上打开插座连接。 如果我将java_socket_socket和java_socket_bind组合在同一C函数中,则JNI调用可以很好地工作,但是当我顺序运行方法时,它不起作用。
这是我的代码
#include <jni.h> // JNI header provided by JDK
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include "Socket.h" // Generated
JNIEXPORT jint JNICALL Java_Socket_socket(JNIEnv *env, jobject thisObj) {
int sockfd;
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
printf("socket creation failed...\n");
return (jint)-1;
} else {
printf("Socket successfully created..\n");
printf("Socket descriptor: %d\n", sockfd);
return (jint) sockfd;
}
}
JNIEXPORT jint JNICALL Java_Socket_bind(JNIEnv *env, jobject thisObj, jint sockfd, jint port) {
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
int c_sockfd = (int) sockfd;
short int c_port = (int) port;
printf("socket binding sockfd - %d, port - %d\n", c_sockfd, c_port);
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(c_port);
printf("htons - %d\n", htons(c_port));
int one = 1;
int res = setsockopt(c_sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
res = setsockopt(c_sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (res < 0) {
perror("setsockopt");
}
printf("sizeof - %d\n", sizeof(servaddr));
if (fcntl(c_sockfd, F_GETFD) != -1 || errno != EBADF) {
printf("fd is valid\n");
} else {
printf("fd is invalid\n");
}
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
printf("Error code: %d\n", errno);
return (jint)-1;
}
else {
printf("Socket successfully binded..\n");
return (jint)0;
}
}
Java代码
public class Socket {
static {
System.load(".../libsocket.so");
}
private native int socket();
private native int bind(int sockFd, int port);
public static void main(String[] args) {
var socket = new Socket();
int sockFd = socket.socket();
System.out.println("sockFd " + sockFd);
int bind = socket.bind(sockFd, 9900);
System.out.println("Bind " + bind);
}
}
输出:
Socket descriptor: 4
socket binding sockfd - 4, port - 9900
htons - 44070
sizeof - 16
fd is valid
socket bind failed...
Error code: 22
如果我从此代码创建C程序,则作为常规C程序,gcc ...&amp;&amp; A.Out
- &gt;然后不会发生错误。有什么原因?
可以是因为文件描述符已关闭吗?
I try to open a socket connection on a Linux machine through JNI.
If I combine Java_Socket_socket and Java_Socket_bind in same C function, the JNI call works perfectly, but it doesn't work when I run methods sequentially.
This is my code
#include <jni.h> // JNI header provided by JDK
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include "Socket.h" // Generated
JNIEXPORT jint JNICALL Java_Socket_socket(JNIEnv *env, jobject thisObj) {
int sockfd;
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
printf("socket creation failed...\n");
return (jint)-1;
} else {
printf("Socket successfully created..\n");
printf("Socket descriptor: %d\n", sockfd);
return (jint) sockfd;
}
}
JNIEXPORT jint JNICALL Java_Socket_bind(JNIEnv *env, jobject thisObj, jint sockfd, jint port) {
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
int c_sockfd = (int) sockfd;
short int c_port = (int) port;
printf("socket binding sockfd - %d, port - %d\n", c_sockfd, c_port);
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(c_port);
printf("htons - %d\n", htons(c_port));
int one = 1;
int res = setsockopt(c_sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
res = setsockopt(c_sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (res < 0) {
perror("setsockopt");
}
printf("sizeof - %d\n", sizeof(servaddr));
if (fcntl(c_sockfd, F_GETFD) != -1 || errno != EBADF) {
printf("fd is valid\n");
} else {
printf("fd is invalid\n");
}
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
printf("Error code: %d\n", errno);
return (jint)-1;
}
else {
printf("Socket successfully binded..\n");
return (jint)0;
}
}
Java code
public class Socket {
static {
System.load(".../libsocket.so");
}
private native int socket();
private native int bind(int sockFd, int port);
public static void main(String[] args) {
var socket = new Socket();
int sockFd = socket.socket();
System.out.println("sockFd " + sockFd);
int bind = socket.bind(sockFd, 9900);
System.out.println("Bind " + bind);
}
}
Output:
Socket descriptor: 4
socket binding sockfd - 4, port - 9900
htons - 44070
sizeof - 16
fd is valid
socket bind failed...
Error code: 22
If I create C program from this code, and as regular C program, gcc ... && a.out
-> then no error occurs. What can be reason?
Can it be because file descriptor is closed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于,您将
af_unix
套接字视为af_inet
一个。您不能使用sockaddr_in
作为af_unix
套接字,也无法将其绑定到IP地址。我认为您已经在套接字定义代码中制作了错字。而不是
它应该是
The issue is that you're treating
AF_UNIX
socket asAF_INET
one. You can't usesockaddr_in
forAF_UNIX
socket and also you can't bind it to an IP address.I think that you've made a typo in your socket definition code. Instead of
it should be