2016-01-11 36 views
2

我知道java需要使用第三方庫來使用unix套接字。我使用junixsocket如何在java中的unix套接字上發送原始數據包

如何在沒有特定文件路徑名的java unix套接字上發送未連接的數據報?

我需要發送一些數據(比如一個IP地址)給一個作爲服務器的應用程序,並寫在c。我的java代碼將是一個客戶端。我不希望它依賴於路徑,因爲在服務器端,c代碼沒有在特定路徑上監聽,而是在原始unix套接字上輪詢,該套接字定義爲socket(AF_UNIX, SOCK_RAW, 0);,它沒有特定的文件路徑名稱。謝謝!

這是c服務器代碼中的一部分,它使用poll()函數在原始unix套接字上偵聽。 main函數位於底部,輪詢位於main之上的event_loop()函數中。

#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; 
} 
+1

我沒有理由發佈C代碼。問題只關於Java。順便說一句:**特定**問題是什麼?學習[問]。 – Olaf

+0

我如何在java中的unix套接字上發送一個未連接的數據報,而不使用filepathname。 c代碼可能是有用的,看看服務器如何收聽 – Pheonix7

回答

0

This ULSE answer說,在一般情況下,名稱更少的資源(如您的插座)只能連接到來自同一過程的孩子,通過自己的資源描述(進程內部整數在創建時由內核分配的ID)。

在你的C代碼,openlispsck(服務器AF_UNIXSOCK_RAW資源描述符,你希望連接到插座)是一個全局變量,因此提供給其他正在運行的並行線程從同一進程催生了(它是也複製到lookupsfds全局陣列)。客戶端pthread可以通過sendto調用使用此套接字的資源描述符與服務器pthread進行通信;正在偵聽套接字的服務器pthread將處理髮送的任何內容。

因此,您不太可能設法從Java或其他任何進程與該套接字進行通信。即使你知道資源描述符,在同一過程之外也是無用的。 如果您可以修改C代碼,請給您的套接字路徑。如果您無法修改C代碼,您仍然可以在服務器進程的/proc條目中的某處找到目標套接字;但我不知道你將如何設法從訪問另一個進程。

+0

好,有趣的知道。但是c服務器代碼從來不會執行綁定,所以即使我要修改代碼,我也無法給它一個路徑。 – Pheonix7

+0

好吧,修改恰好是在創建套接字之後添加一個'bind(openlispsck,(sockaddr *)&server_address,server_len);'。網上有很多[示例](https://cygwin.com/ml/cygwin/2000-08/msg00784.html),介紹如何填充'server_address'並計算相應的'server_len'。 – tucuxi

相關問題