2012-04-10 74 views
0

我寫了這個程序,從IPv6的eth0上發送和接收數據包:僵局插座

#include<sys/socket.h> 
#include<sys/types.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <netdb.h> 
#include <errno.h> 
#include <net/if.h> 
#include <sys/ioctl.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
int main() { 

    int sock,i; 
    struct sockaddr_in6 *address; 
    struct protoent *proto; 
    struct ifreq ethreq, Interface, Interface1; 
    unsigned char buffer[2048]; 
    unsigned char tbuff[2048]; 
    unsigned char *iphead, *ethhead,*phead; 
    static const uint8_t mys6_addr[16]={0x54,0x04,0x20,0x49,0x0e,0x40,0xc7,0x03,0xa0}; 

    //open socket for receive ipv6 packet 
    sock=socket(AF_INET6, SOCK_RAW,255); 
    //control error 
    if(sock<0) { 
     perror("socket"); 
     exit(1); 
    } 

    strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); 
    if (ioctl(sock,SIOCGIFFLAGS, &ethreq) == -1) { 
     perror("ioctl"); 
     close(sock); 
     exit(1); 
    } 

    ethreq.ifr_flags |= IFF_PROMISC; 
    if (ioctl(sock, SIOCSIFFLAGS, &ethreq) == -1) { 
     perror("ioctl"); 
     close(sock); 
     exit(1); 
    } 

    //bind to sock with eth0 
    memset(&Interface, 0, sizeof(Interface)); 
    strncpy(Interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ); 
    if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &Interface, sizeof(Interface))<0) 
     close(sock); 

    //open the RAW socket for sendto 
    int s = socket (AF_INET6, SOCK_RAW, 255); 
    struct sockaddr_in6 sin6; 
    memset(&sin6,0,sizeof(sin6)); 
    sin6.sin6_family = AF_INET6; 
    sin6.sin6_port = htons(0); 
    memcpy(sin6.sin6_addr.s6_addr, mys6_addr, sizeof(mys6_addr)); 
    //bind the sock descriptor with eth0 
    memset(&Interface1, 0, sizeof(Interface1)); 
    strncpy(Interface1.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ); 
    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &Interface1, sizeof(Interface1)) < 0) { 
     close(s); 
    } 
    while (1) { 

     printf("----------------------\n"); 
     i = recv(sock, buffer, sizeof(buffer), 0); 
     printf("%d bytes read\n", i); 
     // check header size: Ethernet = 14, IP = 20, TCP = 8 (sum = 42) 
     i=43; 
     if (i < 42) { 
      perror("recvfrom():"); 
      printf("Incomplete packet (errno is %d)\n", errno); 
      close(sock); 
      exit(0); 
     } 
     phead = buffer + 14; // (skip ethernet header) 
     memcpy(tbuff,phead,i-14); 
     iphead=tbuff; 
     if (*iphead == 0x45) { 
      int ptrindex= iphead[9]; 
      switch(ptrindex){ 

      case 1: 
      printf("The transport protocl is:ICMP\n"); 
      break; 
      case 2: 
      printf("The transport protol is:IGMP\n"); 
      break; 
      case 6: 
      printf("The transport protocol is:TCP\n"); 
      break; 
      case 17: 
      printf("The transport protocol is:UDP\n"); 
      break; 
      case 103: 
      printf("The transport protocol is:PIM\n"); 
      break; 
      default: 
      printf("The transport protocol is:%d\n",iphead[9]); 
     }   
     //printf("%d",*ptrindex); 
     // printf("\n The transport protocol is :%u\n",iphead[9]); 
     printf("Source Address: %d.%d.%d.%d, Port: %d\n", 
     iphead[12], iphead[13], iphead[14], iphead[15], (iphead[20] << 8) + iphead[21]); 
     printf("Dest Address: %d.%d.%d.%d, Port: %d\n", 
     iphead[16], iphead[17], iphead[18], iphead[19], (iphead[22] << 8) + iphead[23]); 


     /* if(sendto(s,tbuff,i-14,0,(struct sockaddr_in6 *)&sin6,sizeof(sin6))<0) 
     printf("error\n"); */ 

     if(send(s,tbuff,i-14,0)<0) { 
      printf("error\n"); 

     } else { 
      printf("\nThe received packet is send\n"); 
     } 

     memset(buffer,0,sizeof(buffer)); 
     memset(tbuff,0,sizeof(tbuff)); 

     } else{ 
      printf("The non ip had received"); 
     } 

    } 
    close(sock); 
    return 0; 
} 

最的代碼是我讀了問題的一部分,但現在我不remembert什麼是。該程序在printf(「---------------- \ n」)處於死鎖狀態。爲什麼?你可以幫我嗎?

+0

兩件事。 1)您可能需要考慮將程序的邏輯分解爲不同的方法,以使其更具可讀性,並且易於調試。 2)我們無法爲您讀取您的代碼;請將其縮小爲一個簡單,簡短,獨立的[可編譯]示例。見[sscce.org](http://www.sscce.org)。 – Makoto 2012-04-10 22:14:02

回答

0

死鎖是一個環形的鎖鏈。這裏沒有鎖,因此也沒有死鎖。發生的一切是recv()阻止等待輸入到達。