原始套接字:接收打印垃圾值(Raw Sockets : Receiver printing garb

2019-10-31 17:17发布

我想整个使用发射机和使用原始套接字的接收程序的字符数组发送。 我能够获得在接收端发送的字节数正确,但打印出来的值都是垃圾。 有人能帮助我在这里?

发射机:

int create_raw_socket(char *dev) 
{   
struct sockaddr_ll sll;
struct ifreq ifr;
int fd, ifi, rb;

bzero(&sll, sizeof(sll)); 
    bzero(&ifr, sizeof(ifr));

fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

assert(fd != -1);

strncpy((char *)ifr.ifr_name, dev, IFNAMSIZ);
ifi = ioctl(fd, SIOCGIFINDEX, &ifr);
assert(ifi != -1);
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
rb = bind(fd, (struct sockaddr *)&sll,sizeof(sll));
assert(rb != -1);

return fd;  
 }


int SendPacket(char *dev ,unsigned char *send_packet, int packet_len) 
{
   int num_sent= 0;
   int sockaddress = create_raw_socket(dev);

   if((num_sent = write(sockaddress, &send_packet, packet_len)) != packet_len)
     { 

         close(sockaddress);
          return 0;
     } 
   else
     { 
        close(sockaddress);
         return 1; 
     }

  }


int main(int argc, char**argv)
{
   int x,fd,s; 

    char *send_packet="HELLO";

   int len = sizeof(send_packet);

   while(1)
   {

   if(!SendPacket((argv[1]), send_packet, len))
     perror("Error sending packet");
   else
     printf("Packet sent successfully with payload : %s\n" ,send_packet);
   }
    return 0; 
 }

接收器:

int main(int argc, char **argv)
{
 struct sockaddr addr;
 int sock_fd, fromlen,s;
 char buf[PACKET_LENGTH];
 char *dev = argv[1];


 while(1)
 {

   fromlen=sizeof(addr);
   sock_fd = create_raw_socket(dev);   /* Creating the raw socket */
   int x= recvfrom(sock_fd,&buf,sizeof(buf),0,&addr,&fromlen);
   printf("\n Number of bytes of data received is %d \n",x);

   printf("\nPayload  Received from client... is %s \n", buf);

   close(sock_fd);

 }
 return 0;
 }

Answer 1:

更改

write(sockaddress, &send_packet, packet_len)

write(sockaddress, send_packet, packet_len)

send_packet已经是缓冲区的地址发送,如果你把这个地址的地址(更准确地说是变量保存地址的地址),你会读错内存缓冲区

同样,对于recvfrom

recvfrom(sock_fd, buf, sizeof(buf), 0, &addr, &fromlen)


Answer 2:

你有几个问题:

  1. 这条线

     if((num_sent = write(sockaddress, &send_packet, packet_len)) != packet_len) 

    应该说只是send_packet ,而不是&send_packetsend_packet是指向所需的分组数据的指针,所以没有必要采取其地址-你不想写出来的是指针到数据包的字面地址,只是根本行不通。

  2. 这是错误的:

     char *send_packet="HELLO"; int len = sizeof(send_packet); 

    sizeof(send_packet)将永远是你的系统,通常是4或8个字节上的指针的大小。 你真的想要任一声明send_packet作为数组的类型(例如char send_packet[] = ... ),或使用strlen计算在运行时其长度(例如int len = strlen(send_packet) + 1; 在你的情况,你要么发送数据太少(4个字节)或过多的数据(8个字节),这两者是有问题的。

  3. printf在客户端代码假定接收到的数据是空终止,它也不一定。 您应该手动空终止打印(或使用其他任何字符串函数,对于这个问题)之前的数据,或者告诉printf多少数据打印的限制。 我建议空的结束它像这样:

     char buf[PACKET_LENGTH + 1]; // +1 for null terminator int x = recvfrom(sock_fd,buf,PACKET_LENGTH,0,&addr,&fromlen); if(x >= 0) buf[x] = 0; 
  4. 你的代码有差const正确性。 SendPacket应该采取const char*代替char*参数,和send_packet要么被声明为char[]或作为const char* 。 从字符串文字的转换char*已被废弃,应在所有新的C代码来避免。



Answer 3:

到达串字符的连接,直到用printf来打印缓冲区将打印字符串。 如果你看到原始字符串,然后垃圾字符,这可能是原因。

通过recvfrom的返回的最后一个字节后,您或许应该引入一个0,否则你将打印任何值是在内存recvfrom的没有覆盖。 它甚至可以尝试缓冲外部访问内存。

尝试添加类似:

int x= recvfrom(sock_fd,&buf,sizeof(buf) - 1,0,&addr,&fromlen);
buf[x - 1] = 0;

注:改变的是什么读取的最大尺寸,它仅仅是如何做到这一点的例子。



文章来源: Raw Sockets : Receiver printing garbage values