I have another question :) I have a simple UDP server in C that reads some bytes applies some decode to those bytes and when it has a STRING of the form ################ he sends it throug UDP to another server in C. Here is the code for my C server that is called preprocesamiento.c Im posting the whole thing cos is easyer but maybe this has nothing to do with my problem.
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#define MAXBUF 512
#define SENDING 0x52
#define RESIVING 0xB4
#define TYPE 0xA3F0
int createSocket();
char *unbase64(unsigned char *input, int length);
/* This function recives bytes(ASCII numbers) and returns the char */
void cambiarAChars(char* bytes, char* result)
{
unsigned int ch;
char a[4];
char buff[50];
strcpy(result,"");
int i=0;
while(i<strlen(bytes))
{
if(bytes[i]=='1')
{
a[0]=bytes[i];
a[1]=bytes[i+1];
a[2]=bytes[i+2];
a[3]='\0';
i=i+3;
}
else
{
a[0]=bytes[i];
a[1]=bytes[i+1];
a[2]='\0';
i=i+2;
}
ch = atoi(a);
sprintf(buff,"%c",ch);
strcat(result,buff);
}
}
/*this is the message that is going to be sent to the other server*/
char msg[MAXBUF];
/*this is the bytes recived*/
char bytes[MAXBUF];
void loadConfig(struct sockaddr_in *udpServer,struct sockaddr_in *thisServer,unsigned char *file);
int sendDataToServerXX(struct sockaddr_in *udpServer, int udpSocket);
int *useStdrr;
int *maxRequests;
int returnStatus;
int main(int argc, char* argv[])
{
if (argc < 2)
{
fprintf(stderr, "Usage: %s <file.config adress>\n", argv[0]);
exit(1);
}
useStdrr=malloc(sizeof(int));
maxRequests=malloc(sizeof(int));
struct sockaddr_in udpServer,thisServer,udpClient;
loadConfig(&udpServer,&thisServer, argv[1]);
int thisServerSocket = createSocket();
int udpSocket=createSocket();
int addrlen;
printf("Listening on.. %d \n",thisServer.sin_port);
thisServer.sin_family = AF_INET;
returnStatus = bind(thisServerSocket, (struct sockaddr*)&thisServer, sizeof(thisServer));
if (returnStatus == 0) {
fprintf(stderr, "Bind completed!\n");
}
else {
fprintf(stderr, "Could not bind to address \n" );
close(thisServerSocket);
exit(1);
}
/*En este while infinito estamos esperando los datos de las tramas*/
while (1)
{
addrlen = sizeof(udpClient);
/* How to resive a struct? */
returnStatus = recvfrom(thisServerSocket,(char*)&bytes, sizeof(bytes), 0,
(struct sockaddr*)&udpClient, &addrlen);
if (returnStatus == -1) {
fprintf(stderr, "Could not receive message!\n");
}
else {
printf("Lo que llego: %s \n",bytes);
/*Primero quitamos el 0 y 1 y guardamos el nuevo arreglo en p*/
bytes[strlen(bytes)-1]='\0';
char p[strlen(bytes)];
int i=0;
while(bytes[i+1]!='\0'){
p[i]=bytes[i+1];
i++;
}
/*esto simula la cambiada a base10 de base64*/
char *result=malloc(512);
char *p2=malloc(sizeof(p)+1);
strcpy(p2,p);
cambiarAChars(p2,result);
strcat(result,"\n\0");
printf("TAMANO: %d \n",strlen(result));
char *output = unbase64(result, strlen(result));
printf("Unbase64: %s\n", output);
msg[0]='%';
strcat(msg,output);
int f=strlen(msg);
msg[f]='%';
msg[f+1]='\0';
printf("Voy a mandar: %s \n",msg);
sendDataToServerXX(&udpServer,udpSocket);
free(output);
}
}
close(thisServerSocket);
close(udpSocket);
}
int createSocket()
{
/* create a socket */
int Socket;
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if (Socket == -1)
{
if(*useStdrr)
{
fprintf(stderr, "Could not create a socket!\n");
}
exit(1);
}
else {
printf("Socket created.\n");
}
return Socket;
}
void loadConfig(struct sockaddr_in *udpServer,struct sockaddr_in *thisServer, unsigned char *file)
{
char line[256];
int linenum=0;
FILE* f = fopen(file, "r");
while(fgets(line, 256, f) != NULL)
{
char atribute[256], value[256];
linenum++;
if(line[0] == '#'||line[0] == ' ') {
continue;
}
else{
if(sscanf(line, "%s %s", atribute, value) != 2)
{
fprintf(stderr, "Syntax error, line %d\n", linenum);
continue;
}
if(!strcmp(atribute,"server_address" ))
{
if(!strcmp(value,""))
{
udpServer->sin_addr.s_addr = htonl(INADDR_ANY);
}
else{
udpServer->sin_addr.s_addr = inet_addr(value);
}
}
else if(!strcmp(atribute,"server_port"))
{
udpServer->sin_port = htons(atoi(value));
}
else if(!strcmp(atribute,"print_message_details"))
{
if(!strcmp(value,"ON"))
{
*useStdrr=1;
}
else
{
*useStdrr=0;
}
}
else if(!strcmp(atribute,"request_count"))
{
*maxRequests=5;
}
else if(!strcmp(atribute,"valor_que_viene_del_cohete_simulado"))
{
}
else if(!strcmp(atribute,"this_server_address"))
{
if(!strcmp(value,""))
{
thisServer->sin_addr.s_addr = htonl(INADDR_ANY);
}
else{
thisServer->sin_addr.s_addr = inet_addr(value);
}
}
else if(!strcmp(atribute,"this_server_port"))
{
thisServer->sin_port = htons(atoi(value));
}
}
}
}
int sendDataToServerXX(struct sockaddr_in *udpServer, int udpSocket)
{
udpServer->sin_family = AF_INET;
int in=0;
int boolv=0;
while(in<*maxRequests)
{
in++;
returnStatus = sendto(udpSocket,(char*) &msg, sizeof(msg), 0,
(struct sockaddr*)udpServer, sizeof(*udpServer));
if (returnStatus == -1) {
if(*useStdrr)
{
fprintf(stderr, "Could not send message!\n");
}
}
else {
printf("Datos enviados al servidor xx.\n");
memset(msg, 0, strlen(msg));
in=*maxRequests;
boolv=1;
}
}
if(!boolv)
{
if(*useStdrr)
{
fprintf(stderr, "fixed number of requests finished.. no reply.\n");
}
}
return 0;
}
char *unbase64(unsigned char *input, int length)
{
BIO *b64, *bmem;
char *buffer = (char *)malloc(length);
memset(buffer, 0, length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf(input, length);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
Ok so i made a simulator that sends data to this server... basically a UDP client that sends bytes as i want them. And the connection and the whole thing works very nice :). Now im trying to connect to the real tester, which is a java jar that sends data as my server wants it through UDP. The only problem is that i dont have the java source code, because its not mine... But the program seems to run smoothly (the java jar) But when i check my server no connections where recived. And yeah im waiting in the right port and both programs the C and Java are running in the same machine (UBUNTU).
I post my client simulator made in C that works very nice with this server.
Sorry its a bit long cos i load from a config file:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAXBUF 1024
#define SENDING 0x52
#define RESIVING 0xB4
#define TYPE 0xA3F0
int createSocket();
char msg[MAXBUF];
void loadConfig(struct sockaddr_in *udpServer, char *file);
int *useStdrr;
int *maxRequests;
int *timeOut;
int main(int argc, char* argv[])
{
int returnStatus;
int addrlen;
struct sockaddr_in udpClient, udpServer;
char buf[MAXBUF];
useStdrr=malloc(sizeof(int));
maxRequests=malloc(sizeof(int));
timeOut=malloc(sizeof(int));
/*ms.timezone="AES";*/
if (argc < 2)
{
fprintf(stderr, "Usage: %s <file.config adress>\n", argv[0]);
exit(1);
}
int udpSocket=createSocket();
udpServer.sin_family = AF_INET;
loadConfig(&udpServer, argv[1]);
/*how to send a struct here?*/
int in=0;
int boolv=0;
printf("Request number %i\n",*maxRequests);
while(in<*maxRequests)
{
in++;
printf("Request number %i\n",in);
printf("Adresss::: %d\n",udpServer.sin_addr.s_addr);
printf("PORT:::: %i\n",udpServer.sin_port);
returnStatus = sendto(udpSocket,(char*) &msg, sizeof(msg), 0,
(struct sockaddr*)&udpServer, sizeof(udpServer));
if (returnStatus == -1) {
if(*useStdrr)
{
fprintf(stderr, "Could not send message!\n");
}
}
else {
printf("Message sent.\n");
/* message sent: look for confirmation */
/*
addrlen = sizeof(udpServer);
returnStatus = recvfrom(udpSocket, (char*) &msg, sizeof(msg), 0,
(struct sockaddr*)&udpServer, &addrlen);
if (returnStatus == -1) {
if(*useStdrr)
{
fprintf(stderr, "Did not receive confirmation!\n");
}
}
else {
printf("Second: %s\n", msg);
*/
in=*maxRequests;
boolv=1;
/*
}*/
}
}
if(!boolv)
{
if(*useStdrr)
{
fprintf(stderr, "fixed number of requests finished.. no reply.\n");
}
}
close(udpSocket);
return 0;
}
int createSocket()
{
/* create a socket */
int Socket;
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if (Socket == -1)
{
if(*useStdrr)
{
fprintf(stderr, "Could not create a socket!\n");
}
exit(1);
}
else {
printf("Socket created.\n");
}
return Socket;
}
void loadConfig(struct sockaddr_in *udpServer, char *file)
{
char line[256];
int linenum=0;
FILE* f = fopen(file, "r");
while(fgets(line, 256, f) != NULL)
{
char atribute[256], value[256];
linenum++;
if(line[0] == '#'||line[0] == ' ') {
continue;
}
else{
if(sscanf(line, "%s %s", atribute, value) != 2)
{
fprintf(stderr, "Syntax error, line %d\n", linenum);
continue;
}
printf("Atribute: %s\n",atribute);
printf("Value: %s\n",value);
if(!strcmp(atribute,"server_address" ))
{
if(!strcmp(value,""))
{
udpServer->sin_addr.s_addr = htonl(INADDR_ANY);
}
else{
udpServer->sin_addr.s_addr = inet_addr(value);
}
}
else if(!strcmp(atribute,"server_port"))
{
udpServer->sin_port = htons(atoi(value));
}
else if(!strcmp(atribute,"print_message_details"))
{
if(!strcmp(value,"ON"))
{
*useStdrr=1;
}
else
{
*useStdrr=0;
}
}
else if(!strcmp(atribute,"request_count"))
{
*maxRequests=atoi(value);
}
else if(!strcmp(atribute,"request_*timeOut"))
{
*timeOut=atoi(value);
}
}
}
}
Now the real QUESTION: Do i have to do something different to connect froma java client to a C from the C server than what i do to connect to another C client? If the answer is no then the problem is in the java project? they tell me its working fine but I think they have tested it with a JAVA server.. Is there any diference? If the problem is in the java project what should i tell them to change for it to work with my C server?
Many thx !!!
Alejandro Casas
There is no such thing as a UDP connection. In UDP, a program just tosses packets at a given port at a given IP. If there is nothing listening at that IP/port, or the receiving program decides to ignore the UDP packets, it gets dropped. If you want an actual connection, you would use TCP.
In addition, some ISP block some types of UDP packets by default
In Java, a TCP socket is called a Socket and a UDP socket is called a DatagramSocket. Make sure you are sending from a DatagramSocket on your Java client.
I haven't done socket programming in C though.
Finally, it would help if you posted some of your Java code.
This is a great example on how to start developing a Java client/server.
Notice it comes from "Computer Networking: A Top Down Approach", by Kurose and Ross
The book has both UDP/TCP examples in JAVA, which are great and I recommend you.
The UDP server/client:
http://systembash.com/content/a-simple-java-udp-server-and-udp-client/
The TCP server/client:
http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/
Related
I am trying to post to a semaphore using JNA on a Linux machine. For some reason, I always receive a 22 error (invalid argument) even for this simple example. In my understanding, should the below code not open a POSIX semaphore, post to it and close it again?
public class Sample {
private static final int O_CREAT = 0x40;
public static void main(String[] args) throws Exception {
File notifier = new File("/tmp", "_test" + new Random().nextInt());
if (!notifier.isFile() && !notifier.createNewFile()) {
throw new IllegalStateException("Could not create notifier: " + notifier);
}
SempahoreLibrary library = Native.load("c", SempahoreLibrary.class);
Pointer semaphore = library.sem_open(notifier.getAbsolutePath(), O_CREAT, 666, 0);
try {
library.sem_post(semaphore);
} finally {
library.sem_close(semaphore);
}
}
interface SempahoreLibrary extends Library {
Pointer sem_open(String name, int flags, int mode, int value) throws LastErrorException;
int sem_post(Pointer pointer) throws LastErrorException;
int sem_close(Pointer pointer) throws LastErrorException;
}
}
I initially couldn't make it work with JNR either (strongly recommended over JNA), and got curious. Writing it in C helped.. :)
An strace on the C port made it clear you don't have to create a file upfront and
then "map" the semaphore to it. Also using the full path is wrong, because
semaphores are created in /dev/shm and the "/" in the path screws
up everything:
futex(0x7f731b1190d0, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/dev/shm/sem.sema", O_RDWR|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=32, ...}) = 0
So you should be able to remove the whole file/path creation and just use a regular non-path name for the semaphore in sem_open. Also the file mode should be octal,
and you should make sure to also load the pthread library - it's required.
Here is a working example in C:
// clang -Wall sema.c -lpthread
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char** argv)
{
sem_t* s = sem_open("notifier", O_CREAT, 0644, 0);
if (!s) {
perror("sem_open");
exit(errno);
}
printf("s: %p\n", s);
sem_post(s);
int value = -1;
sem_getvalue(s, &value);
printf("value: %d\n", value);
sem_wait(s);
sem_getvalue(s, &value);
printf("value: %d\n", value);
sem_close(s);
exit(EXIT_SUCCESS);
}
Here is a working Java version using JNR:
import jnr.ffi.LastError;
import jnr.ffi.LibraryLoader;
import jnr.ffi.Pointer;
import jnr.ffi.Runtime;
public class Semaphore
{
private static final int O_CREAT = 0x40;
public interface SempahoreLibrary
{
Pointer sem_open(String name, int flags, int mode, int value);
int sem_post(Pointer pointer);
int sem_close(Pointer pointer);
}
public static void main(String[] args) throws Exception
{
LibraryLoader<SempahoreLibrary> loader = LibraryLoader.create(SempahoreLibrary.class);
loader.library("c");
loader.library("pthread");
SempahoreLibrary library = loader.load();
jnr.ffi.Runtime runtime = Runtime.getRuntime(library);
Pointer semaphore = library.sem_open("notifier", O_CREAT, 0644, 0);
if (semaphore == null)
{
int errno = LastError.getLastError(runtime);
System.out.println("sem_open: " + errno);
System.exit(errno);
}
System.out.println("semaphore: " + Long.toHexString(semaphore.address()));
try
{
int error = library.sem_post(semaphore);
System.out.println("post: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));
}
finally
{
int error = library.sem_close(semaphore);
System.out.println("close: " + (error == 0 ? "OK" : LastError.getLastError(runtime)));
}
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I know that java needs 3rd party libraries to use unix sockets. Im using junixsocket.
How do i send an unconnected datagram on a unix socket in java without a specific filepathname?
I need to send some data (say an ip address) to an application which acks as a server and is written in c. My java code would be a client. I dont want it to be dependent on a path, as on the server side the c code is not listening on a particular path but is polling on a raw unix socket defined as socket(AF_UNIX, SOCK_RAW, 0); which does'nt have a specific filepath name. Thanks!
This is a part of the server code in c that listens on the raw unix socket with a poll() function. The main functions is at the bottom and the poll is int the event_loop() function just above the main.
#include "lib.h"
#include "udp.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
struct eid_lookup {
union sockunion eid; /* Destination EID */
int rx; /* Receiving socket */
// more parameters.
struct timespec start; /* Start time of lookup */
uint64_t active; /* Unique lookup identifier, 0 if inactive */
union sockunion * mr; /* Point to mapresolver */
};
struct eid_lookup lookups[MAX_LOOKUPS];
struct pollfd fds[MAX_LOOKUPS + 1];
int fds_idx[MAX_LOOKUPS +1];
nfds_t nfds = 0;
struct protoent *proto;
int udpproto;
int seq;
int openlispsck;
static void map_message_handler(union sockunion * mr);
int check_eid(union sockunion *eid);
void new_lookup(union sockunion *eid, union sockunion * mr);
int send_mr(int idx);
int read_rec(union map_reply_record_generic * rec);
size_t
_get_sock_size(union sockunion * eid)
{
size_t ss_len;
switch (eid->sa.sa_family){
case AF_INET:
ss_len = sizeof(struct sockaddr_in);
break;
default:
fprintf(OUTPUT_ERROR, "AF not support::%d\n",eid->sa.sa_family);
return -1;
}
return ss_len;
}
int
sockunioncmp(void * m, void * n)
{
union sockunion * sp, * dp;
sp = m; dp = n;
if(sp->sa.sa_family != dp->sa.sa_family)
return -1;
switch (sp->sa.sa_family){
case AF_INET:
return memcmp(&sp->sin.sin_addr, &dp->sin.sin_addr,sizeof(struct in_addr));
break;
default:
return -1;
}
return -1;
}
/* Process message from Openlis socket */
static void
map_message_handler(union sockunion * mr)
{
struct timespec now;
char msg[PSIZE]; /* buffer for mapping messages */
int n = 0; /* number of bytes received on mapping socket */
union sockunion *eid;
n = read(lookups[0].rx, msg, PSIZE);
clock_gettime(CLOCK_REALTIME, &now);
printf("%" PRIu16 "\n",((struct map_msghdr *)msg)->map_type);
eid = (union sockunion *)CO(msg,sizeof(struct map_msghdr));
printf("map_type: %" PRIu16 "\n",((struct map_msghdr *)msg)->map_type);
//i Added this, but im not sure its fully required. It has some propertyies of the map db
if (((struct map_msghdr *)msg)->map_type == MAPM_MISS_EID) {
printf("Im in the 1 if\n");
eid = (union sockunion *)CO(msg,sizeof(struct map_msghdr));
if (check_eid(eid)) {
printf("Im in the 2 if\n");
new_lookup(eid, mr);
}
}
}
/*Check if an EID-prefix exist in poll */
int
check_eid(union sockunion *eid)
{
int i;
for (i = 1; i < MAX_LOOKUPS; i++)
if (lookups[i].active)
if (!memcmp(eid, &lookups[i].eid, _get_sock_size(eid))){
return 0;
}
return 1;
}
/*Add new EID to poll*/
void
new_lookup(union sockunion *eid, union sockunion * mr)
{
int i,e,r;
uint16_t sport; /* inner EMR header source port */
char sport_str[NI_MAXSERV]; /* source port in string format */
struct addrinfo hints;
struct addrinfo *res;
/* Find an inactive slot in the lookup table */
for (i = 1; i < MAX_LOOKUPS; i++)
if (!lookups[i].active)
break;
if (i >= MAX_LOOKUPS) {
return;
}
/*new socket for map-request */
if ((r = socket(mr->sa.sa_family, SOCK_DGRAM, udpproto)) < 0) {
fprintf(OUTPUT_ERROR, "Error when create new socket\n");
return;
}
/*random source port of map-request */
e = -1;
while (e == -1){
sport = MIN_EPHEMERAL_PORT + random() % (MAX_EPHEMERAL_PORT - MIN_EPHEMERAL_PORT);
sprintf(sport_str, "%d", sport);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = mr->sa.sa_family;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
if ((e = getaddrinfo(NULL, sport_str, &hints, &res)) != 0) {
fprintf(OUTPUT_ERROR, "getaddrinfo: %s\n", gai_strerror(e));
e = -1;
continue;
}
if ((e = bind(r, res->ai_addr, res->ai_addrlen)) == -1) {
fprintf(OUTPUT_ERROR, "bind error to port %s\n", sport_str);
e = -1;
continue;
}
freeaddrinfo(res);
}
memcpy(&lookups[i].eid, eid, _get_sock_size(eid));
lookups[i].rx = r;
lookups[i].sport = sport;
clock_gettime(CLOCK_REALTIME, &lookups[i].start);
lookups[i].count = 0;
lookups[i].active = 1;
if(mr->sa.sa_family == AF_INET)
mr->sin.sin_port = htons(LISP_CP_PORT);
lookups[i].mr = mr;
send_mr(i);
}
/* Send map-request */
int
send_mr(int idx)
{
uint32_t nonce0, nonce1;
int cnt;
union sockunion *eid;
char buf[PSIZE];
struct lisp_control_hdr * lh;
struct ip * ih;
struct ip6_hdr *ih6;
struct udphdr * udp ;
struct map_request_hdr * lcm;
union afi_address_generic * itr_rloc;
union map_request_record_generic * rec;
union afi_address_generic afi_addr_src;
union afi_address_generic afi_addr_dst;
uint8_t * ptr;
int sockaddr_len;
size_t itr_size, ip_len;
char ip[INET6_ADDRSTRLEN];
int mask;
eid = &lookups[idx].eid;
if (lookups[idx].count >= COUNT) {
lookups[idx].active = 0;
close(lookups[idx].rx);
return 0;
}
bzero(buf,PSIZE);
lh = (struct lisp_control_hdr *)buf;
ih = (struct ip *)CO(lh, sizeof(struct lisp_control_hdr));
ih6 = (struct ip6_hdr *)CO(lh, sizeof(struct lisp_control_hdr));
/*choose source/destionation ip */
switch (lookups[idx].mr->sa.sa_family ){
case AF_INET:
afi_addr_dst.ip.afi = AF_INET;
memcpy(&afi_addr_dst.ip.address,(struct in_addr *)&(lookups[idx].mr->sin.sin_addr),sizeof(struct in_addr));
afi_addr_src.ip.afi = AF_INET;
memcpy(&afi_addr_src.ip.address,(struct in_addr *)(src_addr[0]),sizeof(struct in_addr));
udp = (struct udphdr *)CO(ih, sizeof(struct ip));
sockaddr_len = sizeof(struct sockaddr_in);
break;
default:
fprintf(OUTPUT_ERROR,"AF not support\n");
return -1;
}
lcm = (struct map_request_hdr*)CO(udp, sizeof(struct udphdr));
/*build message header*/
/* set all the LISP flags */
uint64_t nonce;
_make_nonce(&nonce);
nonce0 = (uint32_t)(*(uint32_t *)&nonce);
nonce1 = (uint32_t)(*(uint32_t *)(&nonce0+1));
/* set no source EID <AFI=0, addres is empty> -> jump of 2 bytes */
/* nothing to do as bzero of the packet at init */
itr_rloc = (union afi_address_generic *)CO(lcm, sizeof(struct map_request_hdr) + 2);
itr_size = SA_LEN(afi_addr_src.ip.afi);
memcpy(itr_rloc, &afi_addr_src, itr_size);
/* set source ITR */
switch(afi_addr_src.ip.afi){
case AF_INET:
itr_rloc->ip.afi = htons(LISP_AFI_IP);
itr_size = sizeof(struct afi_address);
break;
default:
printf("not supported\n");
return (FALSE);
}
rec = (union map_request_record_generic *)CO(itr_rloc, itr_size);
/* assign correctly the EID prefix */
switch(eid->sa.sa_family){
case AF_INET:
/* EID prefix is an IPv4 so 32 bits (4 bytes) */
rec->record.eid_mask_len = mask = 32;
rec->record.eid_prefix_afi = htons(LISP_AFI_IP);
memcpy(&rec->record.eid_prefix, &(eid->sin.sin_addr), sizeof(struct in_addr));
inet_ntop(AF_INET, (void *)&rec->record.eid_prefix, ip, INET6_ADDRSTRLEN);
ptr = (uint8_t *)CO(rec,4+4);
break;
default:
printf("not supported\n");
return (FALSE);
}
/* set the UDP parameters */
udp->source = htons(lookups[idx].sport);
udp->dest = htons(LISP_CP_PORT);
udp->len = htons((uint8_t *)ptr - (uint8_t *) udp );
udp->check = 0;
/* setup the IP parameters */
switch (lookups[idx].mr->sin.sin_family ){
case AF_INET:
ip_len = (uint8_t *)ptr - (uint8_t *) ih;
ih->ip_hl = 5;
ih->ip_v = 4;
ih->ip_tos = 0;
ih->ip_len = htons(ip_len);
ih->ip_id = htons(0);
ih->ip_off = 0;
ih->ip_ttl = 255;
ih->ip_p = IPPROTO_UDP;
ih->ip_sum = 0;
ih->ip_src.s_addr = afi_addr_src.ip.address.s_addr;
ih->ip_dst.s_addr = eid->sin.sin_addr.s_addr;
ih->ip_sum = ip_checksum((unsigned short *)ih, ip_len);
break;
}
if (sendto(lookups[idx].rx, (void *)buf, (uint8_t *)ptr - (uint8_t *)lh, 0, &(lookups[idx].mr->sa), sockaddr_len) < 0) {
return 0;
} else {
cnt = lookups[idx].count;
lookups[idx].nonce0[cnt] = nonce0;
lookups[idx].nonce1[cnt] = nonce1;
lookups[idx].count++;
char ip2[INET6_ADDRSTRLEN];
if(_debug == LLOG || _debug == LDEBUG){
fprintf(OUTPUT_STREAM, "\n#Send Map-Request to %s:%d <nonce=0x%x - 0x%x>\n", \
sk_get_ip(lookups[idx].mr, ip2) , sk_get_port(lookups[idx].mr),\
nonce0, nonce1);
if(_debug == LDEBUG)
fprintf(OUTPUT_STREAM," EID %s/%d\n",ip,mask);
}
}
return 1;
}
/* Process with map-reply */
int
read_rec(union map_reply_record_generic * rec)
{
fprintf(OUTPUT_STREAM, "\n");
fprintf(OUTPUT_STREAM, "---------------Begin----------------\n");
size_t rlen;
union map_reply_locator_generic * loc;
char buf[BSIZE];
size_t len;
struct map_entry * entry;
uint8_t lcount;
struct prefix eid;
struct mapping_flags mflags;
void * mapping;
struct db_node node;
struct lcaf_hdr *lcaf;
union rloc_te_generic *hop;
void *barr;
node.flags = NULL;
rlen = 0;
bzero(buf, BSIZE);
mapping = NULL;
bzero(&eid, sizeof(struct prefix));
switch(ntohs(rec->record.eid_prefix_afi)){
case LISP_AFI_IP:
eid.family = AF_INET;
eid.u.prefix4 = rec->record.eid_prefix;
inet_ntop(AF_INET, (void *)&eid.u.prefix4, buf, BSIZE);
rlen += sizeof(struct map_reply_record);
break;
default:
fprintf(OUTPUT_STREAM, "unsuported family\n");
return (0);
}
eid.prefixlen = rec->record.eid_mask_len;
lcount = rec->record.locator_count;
bzero(&mflags, sizeof(struct mapping_flags));
mflags.act = rec->record.act;
mflags.A = rec->record.a;
mflags.version = rec->record.version;
mflags.ttl = ntohl(rec->record.ttl);
memcpy(&node.p, &eid, sizeof(struct prefix));
generic_mapping_set_flags(&node, &mflags);
node.info = list_init();
return EXIT_SUCCESS;
loc = (union map_reply_locator_generic *)CO(rec, rlen);
/* ==================== RLOCs ========================= */
while(lcount--){
bzero(buf, BSIZE);
entry = (struct map_entry *)calloc(1, sizeof(struct map_entry));
entry->priority = loc->rloc.priority;
entry->weight = loc->rloc.weight;
entry->m_priority = loc->rloc.m_priority;
entry->m_weight = loc->rloc.m_weight;
entry->r = loc->rloc.R;
entry->L =loc->rloc.L;
entry->p = loc->rloc.p;
lcaf = (struct lcaf_hdr *)&loc->rloc.rloc_afi;
if(ntohs(lcaf->afi) == LCAF_AFI && lcaf->type == LCAF_TE){
struct sockaddr_in hop_inet;
struct sockaddr_in6 hop_inet6;
int pec = 0;
int rtr = 0;
barr = (void *)CO(lcaf,sizeof(struct lcaf_hdr)+ntohs(lcaf->payload_len));
hop = (union rloc_te_generic *)CO(lcaf,sizeof(struct lcaf_hdr));
/* run over pe
if lisp_te
if xTR --> get the first hop
if RTR --> get the hop after RTR
if not lisp_te --> get last hop
*/
hop = (union rloc_te_generic *)CO(lcaf,sizeof(struct lcaf_hdr));
while((char *)hop < (char *)barr){
switch(ntohs(hop->rloc.afi)){
case LISP_AFI_IP:
/* xTR get first hop in pe */
if(!pec && lisp_te && (_fncs & _FNC_XTR)){
entry->rloc.sin.sin_family = AF_INET;
memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr, sizeof(struct in_addr));
hop = loc = barr;
continue;
}
/* RTR get next hop after it in pe */
if(lisp_te && (_fncs & _FNC_RTR)){
if(!rtr){
/* check if hop's ip is rtr's ip */
hop_inet.sin_family = AF_INET;
hop_inet.sin_addr.s_addr = hop->rloc.hop_addr.s_addr;
if (is_my_addr((union sockunion *)&hop_inet))
rtr = 1;
}
else{
entry->rloc.sin.sin_family = AF_INET;
memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr,sizeof(struct in_addr));
hop = loc = barr;
rtr = 0;
continue;
}
}
/* not lisp_te function get last hop */
if( !lisp_te && (CO(hop,sizeof(struct rloc_te) >= (char *)barr )) ){
entry->rloc.sin.sin_family = AF_INET;
memcpy(&entry->rloc.sin.sin_addr, &hop->rloc.hop_addr,sizeof(struct in_addr));
hop = loc = barr;
continue;
}
hop = CO(hop,sizeof(struct rloc_te));
break;
case LISP_AFI_IPV6:
/* xTR get first hop in pe */
if(lisp_te && !pec && (_fncs & _FNC_XTR)){
entry->rloc.sin6.sin6_family = AF_INET6;
memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr, sizeof(struct in6_addr));
hop = loc = barr;
continue;
}
/* RTR get next hop after it in pe */
if(lisp_te && (_fncs & _FNC_RTR)){
if(!rtr){
hop_inet6.sin6_family = AF_INET6;
memcpy(&hop_inet6.sin6_addr,&hop->rloc6.hop_addr,sizeof(struct in6_addr));
if (is_my_addr((union sockunion *)&hop_inet6))
rtr = 1;
}
else{
entry->rloc.sin6.sin6_family = AF_INET6;
memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr,sizeof(struct in6_addr));
hop = loc = barr;
rtr = 0;
continue;
}
}
/* not lisp_te function get last hop */
if( (char *)(hop + sizeof(struct rloc6_te)) > (char *)barr){
entry->rloc.sin6.sin6_family = AF_INET6;
memcpy(&entry->rloc.sin6.sin6_addr, &hop->rloc6.hop_addr,sizeof(struct in6_addr));
hop = loc = barr;
continue;
}
hop = (union rloc_te_generic *)CO(hop,sizeof(struct rloc6_te));
break;
default:
fprintf(OUTPUT_STREAM, "unsuported family\n");
free(entry);
return (0);
}
pec++;
}
loc = barr;
}
else{
switch(ntohs(loc->rloc.rloc_afi)){
case LISP_AFI_IP:
entry->rloc.sin.sin_family = AF_INET;
memcpy(&entry->rloc.sin.sin_addr, &loc->rloc.rloc, sizeof(struct in_addr));
len = sizeof(struct map_reply_locator);
break;
case LISP_AFI_IPV6:
entry->rloc.sin6.sin6_family = AF_INET6;
memcpy(&entry->rloc.sin6.sin6_addr, &loc->rloc6.rloc, sizeof(struct in6_addr));
len = sizeof(struct map_reply_locator6);
break;
default:
fprintf(OUTPUT_STREAM, "unsuported family\n");
free(entry);
return (0);
}
loc = (union map_reply_locator_generic *)CO(loc, len);
}
/* add the locator to the table */
rlen = (char *)loc - (char *)rec;
assert((struct list_t *)node.info);
struct list_entry_t *m;
struct map_entry *n_entry;
if(entry->rloc.sa.sa_family){
if(!(m = list_search(node.info, entry,entrycmp))){
list_insert((struct list_t *)node.info, entry, NULL);
}
else{
/* new rloc exist, only updat priority and pe */
n_entry = (struct map_entry *)m->data;
if(n_entry->priority > entry->priority){
m->data = entry;
free(n_entry);
}
else
free(entry);
}
}
else{
free(entry);
return 0;
}
}
fprintf(OUTPUT_STREAM, " =====================3=====================");
/* add to OpenLISP mapping cache */
if(node.info)
list_destroy((struct list_t *)node.info, NULL);
return (rlen);
}
/* get map-reply */
int
read_mr(int idx)
{
fprintf(OUTPUT_STREAM, "0000000 Im in plugin_openlisp.c 10 000000");
int i;
int rcvl;
char buf[PSIZE];
union sockunion si;
struct map_reply_hdr * lh;
union map_reply_record_generic * lcm;
uint32_t nonce0, nonce1;
socklen_t sockaddr_len;
int rec_len;
char ip[INET6_ADDRSTRLEN];
//printf("get reply\n");
if(lookups[idx].mr->sa.sa_family == AF_INET)
sockaddr_len = sizeof(struct sockaddr_in);
else
sockaddr_len = sizeof(struct sockaddr_in6);
/* read package */
if ((rcvl = recvfrom(lookups[idx].rx,
buf,
PSIZE,
0,
(struct sockaddr *)&(si.sa),
&sockaddr_len)) < 0) {
return 0;
}
/*only accept map-reply with not empty record */
lh = (struct map_reply_hdr *)buf;
if (lh->lisp_type != LISP_TYPE_MAP_REPLY) {
return 0;
}
/* check nonce to see reply for what */
nonce0 = ntohl(lh->lisp_nonce0);
nonce1 = ntohl(lh->lisp_nonce1);
fprintf(OUTPUT_STREAM, "---------------p2--------------\n");
if(_debug == LLOG || _debug == LDEBUG)
fprintf(OUTPUT_STREAM, "\n#Received Map-Reply from %s:%d <nonce=0x%x - 0x%x>\n",\
sk_get_ip(&si, ip) , sk_get_port(&si),\
nonce0,nonce1);
for (i = 0;i <= MAX_COUNT ; i++) {
if (lookups[idx].nonce0[i] == nonce0 && lookups[idx].nonce1[i] == nonce1)
break;
}
if (i > MAX_COUNT)
return 0;
if (lh->record_count <= 0)
return 0;
/* process map-reply */
lcm = (union map_reply_record_generic *)CO(lh,sizeof(struct map_reply_hdr));
for (i = 0; i < lh->record_count; i++){
if( (rec_len = read_rec(lcm)) < 0){
if(_debug == LDEBUG)
fprintf(OUTPUT_ERROR, "Record error\n");
return -1;
}
lcm = (union map_reply_record_generic * )CO(lcm,rec_len);
}
lookups[idx].active = 0;
close(lookups[idx].rx);
return 0;
}
/* Main poll function */
static void
event_loop(void)
{
for (;;) {
int e, i, j, l = -1;
int poll_timeout = INFTIM; /* poll() timeout in milliseconds. We initialize
to INFTIM = -1 (infinity). If there are no
active lookups, we wait in poll() until a
mapping socket event is received. */
struct timespec now, deadline, delta, to, tmp;
//printf("start event_loop\n");
to.tv_sec = timeout;
to.tv_nsec = 0;
nfds = 1;
clock_gettime(CLOCK_REALTIME, &now);
//If lookups inactive continue/salta!
if (!(lookups[i].active)) continue;
deadline.tv_sec = lookups[i].start.tv_sec + (lookups[i].count +1) * timeout;
deadline.tv_nsec = lookups[i].start.tv_nsec;
timespec_subtract(&delta, &deadline, &now);
fds[nfds].fd = lookups[i].rx;
fds[nfds].events = POLLIN;
fds_idx[nfds] = i;
nfds++;
/* Find the minimum delta */
if (timespec_subtract(&tmp, &delta, &to)) {
printf("delta.tv_sec: %d\n",delta.tv_sec);
to.tv_sec = delta.tv_sec;
to.tv_nsec = delta.tv_nsec;
poll_timeout = to.tv_sec * 1000 + to.tv_nsec / 1000000;
printf("poll_timeout = %d \n", poll_timeout);
if (to.tv_sec < 0) poll_timeout = 0;
l = i;
}
} /* Finished iterating through all lookups */
printf("--------------\n");
printf("time_out:%d\n",poll_timeout);
printf("fds:%d\n",fds);
printf("nfds:%d\n",nfds);
printf("Waiting.....\n");
printf("--------------\n");
e = poll(fds, nfds, poll_timeout);
printf("e = %d\n",e);
printf("l = %d\n",l);
if (e < 0) continue;
if (e == 0) // If timeout expires
if (l >= 0) // and slot is defined
send_mr(l); // retry Map-Request
for (j = nfds - 1; j >= 0; j--) {
printf("Type of event that actually occurred = %d\n",fds[j].revents);
if (fds[j].revents == POLLIN) {
printf("j = %d\n",j);
if (j == 0)
map_message_handler(_get_mr());
else
read_mr(fds_idx[j]);
}
}
}
}
/* Main function of thread with intergrate with OpenLisp */
/* Size of socket must be multiple of long (from OpenLISP code)
so size of sockaddr_in6 is 32 instead 28
*/
#define SS_SIZE(ss) \
( (!(ss) || ((struct sockaddr_storage *)(ss))->ss_len == 0) ? \
sizeof(long) : \
1 + ( (((struct sockaddr_storage *)(ss))->ss_len - 1) | (sizeof(long) - 1) ) )
//MAIN
void main(void * data)
{
int i;
struct protoent *proto;
if ((proto = getprotobyname("UDP")) == NULL) {
perror ("getprotobyname");
exit(0);
}
udpproto = proto->p_proto;
openlispsck = socket(AF_UNIX, SOCK_RAW, 0); // The sysem will chose the most appropriate when specifying set to 0
lookups[0].rx = fds[0].fd = openlispsck;
fds[0].events = POLLIN;
fds_idx[0] = -1;
nfds = 1;
/* Initialize lookups[]: all inactive */
for (i = 0; i < MAX_LOOKUPS; i++){
lookups[i].active = 0;
}
event_loop();
pthread_exit(NULL);
return 0;
}
This ULSE answer says that, in general, name-less resources (such as your socket) can only be connected-to from children of the same process, via their resource-descriptor (a process-internal integer ID assigned by the kernel on creation).
In your c-code, openlispsck (the server AF_UNIX, SOCK_RAW resource-descriptor for the socket that you wish to connect to) is a global variable, and therefore available to other running pthreads spawned from the same process (it is also copied over to the lookups and fds global arrays). Client pthreads can then communicate with the server pthread via sendto calls that use this socket's resource-descriptor; the server pthread, which is listening on the socket, will then process whatever is sent.
Therefore, you are highly unlikely to manage to communicate with that socket from another process in Java or anything else. Even if you know the resource-descriptor, it is useless from outside the same process. If you can modify the C-code, give your socket a path. If you can't modify the C-code, you can still find the target socket somewhere in the /proc entry of the server process; but I have no idea how you will manage to access it from another process.
I have been trying to get audio signal from an arduino microphone. First I setup my arduino in Free Running Mode, and then I wait for a message from Processing that is a capital A. When Processing sends the serial signal, my arduino should send back 16 audio amplitude samples. Then, processing should take those 16 audio samples and pass them by the Fast Fourier Transform in orden to get a real time frequency spectrum. However, it seems that my Arduino never detects the capital A, and also, if I try to send the samples from my Arduino without waiting for the capital A, when Processing gets the samples it seems something went wrong with the serial communication. I tried with many arduinos and different serial cables to be sure it was no the problem. Here you are the arduino code:
// Arrays to save our results in
int values[16];
// Define various ADC prescaler
const unsigned char PS_16 = (1 << ADPS2);
const unsigned char PS_32 = (1 << ADPS2) | (1 << ADPS0);
const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1);
const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
// Setup the serial port and pin 2
void setup() {
Serial.begin(115200);
pinMode(2, INPUT);
// set up the ADC
ADCSRA &= ~PS_128; // remove bits set by Arduino library
// you can choose a prescaler from above.
// PS_16, PS_32, PS_64 or PS_128
ADCSRA |= PS_64; // set our own prescaler to 64
}
void loop() {
unsigned int i;
for(i=0;i<16;i++) {
values[i] = analogRead(2);
}
if(Serial.available() > 0) {
char c = Serial.read();
if(c == 'A') {
for(i=0;i<16;i++) {
Serial.println(values[i]);
}
}
}
delay(10);
}
Here you are the processing code:
import processing.serial.*;
import ddf.minim.analysis.*;
FFT fft;
Serial myPort; // Create object from Serial class
void setup()
{
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 115200);
size(800, 600);
background(255);
fft = new FFT(16, 16000);
}
String mensaje;
float[] magnitudes = new float[16];
int contador = 0;
byte request = true;
void draw()
{
if(request) {
myPort.write('A');//Solicita nuevos datos.
request = false;
}
while(!request) {
if(myPort.available()>0) {
mensaje = myPort.readStringUntil(13);
print(" mensaje: "+mensaje);
if(mensaje != null){
magnitudes[contador++] = int(mensaje);
}
}
if(contador >= 15) {
contador=0;
fft.forward(magnitudes);
request = true;
fill(100);
rect(0,0,800,800);
for (int i = 0; i < 15; i++) {
fill(200);
rect(i*30+10, 0, 10, fft.getBand(i) * 0.1);
}
}
}
}
Thank you a lot for your attention!
Environment:
PC sys:windows xp
jdk:1.6
ndk:android-ndk-r9b
compile env:MinGW
Descrpiton:
I'm developing a sip endpoint app, which is based on the opensource sip stack "doubango", in Android device. The socket functions are called using NDK but not directly JAVA. When normally use, it's OK. Then clean the device's memory using some software, or stop Service manully, and make it exit abnormally. Seems that it stops without call function close(socket). Next time when I use, it will throw error calling socket function :sendto(),the errno=1 which means "operation not permitted".
I've added "uses-permission android:name="android.permission.INTERNET""
Does anyone can give me a hand?
PS:I test in devices without ROOT permission, and this issue will happen. But I test a device with ROOT permission, it doesn't happen. Does it matter?
Job Is Done. There are sth mistakes i made in the Java layer. Some parameters i set in Sip stack are wrong.
Here follows the code segment:
int tnet_sockfd_sendto(tnet_fd_t fd, const struct sockaddr *to, const void* buf, tsk_size_t size)
{
tsk_size_t sent = 0;
int ret = -1;
if(fd == TNET_INVALID_FD){
TSK_DEBUG_ERROR("Using invalid FD to send data.");
goto bail;
}
if(!buf || !size){
TSK_DEBUG_ERROR("Using invalid BUFFER.");
ret = -2;
goto bail;
}
while(sent < size){
int try_guard = 10;
#if TNET_UNDER_WINDOWS
WSABUF wsaBuffer;
DWORD numberOfBytesSent = 0;
wsaBuffer.buf = ((CHAR*)buf) + sent;
wsaBuffer.len = (size - sent);
try_again:
ret = WSASendTo(fd, &wsaBuffer, 1, &numberOfBytesSent, 0, to, tnet_get_sockaddr_size(to), 0, 0); // returns zero if succeed
if(ret == 0){
ret = numberOfBytesSent;
}
#else
try_again:
ret = sendto(fd, (((const uint8_t*)buf)+sent), (size-sent), 0, to, tnet_get_sockaddr_size(to)); // returns number of sent bytes if succeed
#endif
if(ret <= 0){
if(tnet_geterrno() == TNET_ERROR_WOULDBLOCK){
TSK_DEBUG_INFO("SendUdp() - WouldBlock. Retrying...");
if(try_guard--){
tsk_thread_sleep(10);
goto try_again;
}
}
else{
***/* Just throw error here*/***
TSK_DEBUG_INFO("errno: %d",tnet_geterrno());
TNET_PRINT_LAST_ERROR("sendto() failed");
}
goto bail;
}
else{
sent += ret;
}
}
bail:
return (size == sent) ? sent : ret;
}
#define tnet_soccket(family, type, protocol) socket((family), (type), (protocol))
tnet_socket_t* tnet_socket_create_2(const char* host, tnet_port_t port_,tnet_socket_type_t type, tsk_bool_t nonblocking, tsk_bool_t bindsocket)
{
tnet_socket_t *sock;
if((sock = tsk_object_new(tnet_socket_def_t))){
int status;
tsk_istr_t port;
struct addrinfo *result = tsk_null;
struct addrinfo *ptr = tsk_null;
struct addrinfo hints;
tnet_host_t local_hostname;
sock->port = port_;
tsk_itoa(sock->port, &port);
sock->type = type;
memset(local_hostname, 0, sizeof(local_hostname));
/* Get the local host name */
if(host != TNET_SOCKET_HOST_ANY && !tsk_strempty(host)){
memcpy(local_hostname, host, tsk_strlen(host)>sizeof(local_hostname)-1 ? sizeof(local_hostname)-1 : tsk_strlen(host));
}
else{
if(TNET_SOCKET_TYPE_IS_IPV6(sock->type)){
memcpy(local_hostname, "::", 2);
}
else{
memcpy(local_hostname, "0.0.0.0", 7);
}
}
TSK_DEBUG_INFO("local_hostname: %s",local_hostname);
/* hints address info structure */
memset(&hints, 0, sizeof(hints));
hints.ai_family = TNET_SOCKET_TYPE_IS_IPV46(sock->type) ? AF_UNSPEC : (TNET_SOCKET_TYPE_IS_IPV6(sock->type) ? AF_INET6 : AF_INET);
hints.ai_socktype = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? SOCK_STREAM : SOCK_DGRAM;
hints.ai_protocol = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? IPPROTO_TCP : IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE
#if !TNET_UNDER_WINDOWS || _WIN32_WINNT>=0x600
| AI_ADDRCONFIG
#endif
;
/* Performs getaddrinfo */
if((status = tnet_getaddrinfo(local_hostname, port, &hints, &result))){
TNET_PRINT_LAST_ERROR("tnet_getaddrinfo(family=%d, hostname=%s and port=%s) failed: [%s]",
hints.ai_family, local_hostname, port, tnet_gai_strerror(status));
goto bail;
}
/* Find our address. */
for(ptr = result; ptr; ptr = ptr->ai_next){
sock->fd = tnet_soccket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET){
continue;
}
/* To avoid "Address already in use" error
* Check issue 368 (https://code.google.com/p/doubango/issues/detail?id=368) to understand why it's not used for UDP/DTLS.
*/
//
if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
TSK_DEBUG_INFO("Socket Type: Stream");
if ((status = tnet_sockfd_reuseaddr(sock->fd, 1))) {
// do not break...continue
}
}
if(bindsocket){
/* Bind the socket */
if((status = bind(sock->fd, ptr->ai_addr, ptr->ai_addrlen))){
TNET_PRINT_LAST_ERROR("bind to [%s:%s]have failed", local_hostname, port);
tnet_socket_close(sock);
continue;
}
/* Get local IP string. */
if((status = tnet_get_ip_n_port(sock->fd , tsk_true/*local*/, &sock->ip, &sock->port))) /* % */
//if((status = tnet_getnameinfo(ptr->ai_addr, ptr->ai_addrlen, sock->ip, sizeof(sock->ip), 0, 0, NI_NUMERICHOST)))
{
TNET_PRINT_LAST_ERROR("Failed to get local IP and port.");
tnet_socket_close(sock);
continue;
}
}
/* sets the real socket type (if ipv46) */
if(ptr->ai_family == AF_INET6) {
TNET_SOCKET_TYPE_SET_IPV6Only(sock->type);
}
else{
TNET_SOCKET_TYPE_SET_IPV4Only(sock->type);
}
break;
}
/* Check socket validity. */
if(!TNET_SOCKET_IS_VALID(sock)) {
TNET_PRINT_LAST_ERROR("Invalid socket.");
goto bail;
}
#if TNET_UNDER_IPHONE || TNET_UNDER_IPHONE_SIMULATOR
/* disable SIGPIPE signal */
{
int yes = 1;
if(setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))){
TNET_PRINT_LAST_ERROR("setsockopt(SO_NOSIGPIPE) have failed.");
}
}
#endif /* TNET_UNDER_IPHONE */
/* Sets the socket to nonblocking mode */
if(nonblocking){
if((status = tnet_sockfd_set_nonblocking(sock->fd))){
goto bail;
}
}
bail:
/* Free addrinfo */
tnet_freeaddrinfo(result);
/* Close socket if failed. */
if(status){
if(TNET_SOCKET_IS_VALID(sock)){
tnet_socket_close(sock);
}
return tsk_null;
}
}
return sock;
}
int tnet_sockfd_reuseaddr(tnet_fd_t fd, int reuseAddr)
{
if (fd != TNET_INVALID_FD) {
int ret;
#if defined(SOLARIS)
static const char yes = '1';
static const char no = '0';
#else
static const int yes = 1;
static const int no = 0;
#endif
if ((ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)(reuseAddr ? &yes : &no), sizeof(int)))) {
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEADDR, fd=%d) have failed", fd);
return ret;
}
// #if defined(SO_REUSEPORT)
if ((ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char*)(reuseAddr ? &yes : &no), sizeof(int)))) {
TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEPORT, fd=%d) have failed", fd);
return ret;
}
// #endif
return 0;
}
return -1;
}
#define tnet_sockfd_set_nonblocking(fd) tnet_sockfd_set_mode(fd, 1)
int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking)
{
if(fd != TNET_INVALID_FD)
{
#if TNET_UNDER_WINDOWS
ULONG mode = nonBlocking;
if(ioctlsocket(fd, FIONBIO, &mode))
//if(WSAIoctl(fd, FIONBIO, &nonblocking, sizeof(nonblocking), NULL, 0, NULL, NULL, NULL) == SOCKET_ERROR)
{
TNET_PRINT_LAST_ERROR("ioctlsocket(FIONBIO) have failed.");
return -1;
}
#else
int flags;
if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
TNET_PRINT_LAST_ERROR("fcntl(F_GETFL) have failed.");
return -1;
}
if(fcntl(fd, F_SETFL, flags | (nonBlocking ? O_NONBLOCK : ~O_NONBLOCK)) < 0){
TNET_PRINT_LAST_ERROR("fcntl(O_NONBLOCK/O_NONBLOCK) have failed.");
return -1;
}
#endif
// int on = 1;
// ioctl(fd, FIONBIO, (char *)&on);
}
return 0;
}
I have a C++ class that uses a JNI JVM to run a Java method. For whatever reason my program is working for 3 iterations and on the 3rd loop the JVM crashes with a SIGSEGV.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f2af5de1c81, pid=7669, tid=139822523557696
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x7ac81]
This code is not complete at all.
#include <string>
#include <thread>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include "imgsearch.h"
#define PORT "8675"
#define BACKLOG 10
JNIEnv* create_vm() {
JavaVM* j;
JNIEnv* e;
JavaVMInitArgs j_args;
JavaVMOption opts;
j_args.version = JNI_VERSION_1_6;
j_args.nOptions = 1;
j_args.ignoreUnrecognized = 0;
char* cp = (char *)"-Djava.class.path=.:./lucene-4.4.0/analysis/common/lucene-analyzers-common-4.4.0.jar:./lucene-4.4.0/core/lucene-core-4.4.0.jar:./lucene-4.4.0/queryparser/lucene-queryparser-4.4.0.jar";
opts.optionString = cp;
j_args.options = &opts;
JNI_CreateJavaVM(&j, (void**)&e, &j_args);
return e;
}
JNIEnv* env = create_vm();
JavaVM* jvm;
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
void sockcom(int csock) {
std::cout << "Yeah!" << std::endl;
}
int main(int argc, char *argv[]) {
env->GetJavaVM(&jvm);
std::string fP = "features/esp.feature";
ImgSearch *iS;
iS = new ImgSearch();
iS->LoadFeatures(fP);
//iS->BuildClusters(150000, 15);
//iS->ClustersToFile("output.clusters");
iS->FileToClusts("output.clusters");
iS->BuildIndex();
//iS->IndexToFile("output.index");
//iS->FileToIndex("output.index");
//iS->FindNeighbors();
//iS->NeighborsToFile("output.neighbors");
iS->FileToNeighbors("output.neighbors");
iS->BagOfWords("features/imglist.txt", "features/esp.size", "coll/output.bagofwords");
iS->BuildLuceneIndex("coll/output.bagofwords");
//std::string queryfile = "queries/query1.pgm";
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}
freeaddrinfo(servinfo); // all done with this structure
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); }
printf("server: waiting for connections...\n");
while(1) { // main accept() loop
int pipefd[2];
int pres = pipe(pipefd);
if (pres < 0) {
perror("pipe");
continue;
}
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
std::thread th(sockcom, new_fd);
th.detach();
std::string queryfile = "queries/query3.pgm";
iS->Search(queryfile);
}
jvm->DestroyJavaVM();
return 0;
}
So iS->Search(queryfile); basically is the following:
void ImgSearch::Search(std::string &filePath) {
ImgQuery newQuery(filePath, Ndx, WORDS);
newQuery.ExtractKeyPoints();
newQuery.FindNeighbors();
newQuery.BagOfWords();
newQuery.LuceneSearch();
return;
// Error Checking?
}
Where the LuceneSearch function is the only one that uses the JNI JVM.
void ImgQuery::LuceneSearch() {
jclass qcls = env->FindClass("BatchSearch");
if (qcls == NULL) std::cout << "BatchSearch: Not Found." << std::endl;
jmethodID qmid = env->GetStaticMethodID(qcls, "main", "()V");
env->CallStaticVoidMethod(qcls, qmid);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
}
std::cout << "Still working..." << std::endl;
return;
// Error Checking?
}
Basically, what I am wondering is A) do you see anything obviously wrong? and B) How do you properly reuse a JVM throughout a project?
EDIT: Is there a way to wait for a JVM to be ready?