免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1893 | 回复: 4
打印 上一主题 下一主题

[网络] 为什么会重复收取同一个数据包 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-02 10:58 |只看该作者 |倒序浏览
RT 最近在学习写一个数据包转发的程序 可是在写好测试的时候发现总是会重复收发同一个数据包 比如我在一端发送一个A数据包 但是在另一端却收到了5个一模一样的A包 请教各种大神这会是什么原因造成的?

源码如下。。。不胜感激

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <string.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h> //xin hao xiang tou wen jian
#define MAX 10240


char buf_eth0[MAX];
volatile int num0,lenth0;
char buf_eth1[MAX];
volatile int num1,lenth1;
sem_t sem0,sem1,sem2,sem3;



void *recv_eth0(void* attr)
{
int *sockid;
int ret=0,recv0,i,r,old;
struct ethhdr *eth;
struct iphdr *iph;
char *px;
sockid = (int*)attr;



while(1)
        {
         sem_wait(&sem2);
         if(MAX - ret <100)
                {
                 ret = 0;
                }
         recv0 = recv(*sockid,&buf_eth0[ret],MAX-ret,0);
         
         if(recv0 == 0)
                {
                 sem_post(&sem2);
                 continue;
                }
       
         px = &buf_eth0[ret];
         eth = (struct ethhdr*)px;
         iph = (struct iphdr*)(px+sizeof(struct ethhdr));
         char *s1 = inet_ntoa(*(struct in_addr *)&iph->daddr);
         char *s2 = "192.168.1.233";
         r = strcmp(s1,s2);
         if((r == 0)||(iph->protocol > 100))
                {
                  old = ret;
                       lenth0 = ret;
                   
                   num0 = recv0;
                   ret = ret + recv0;

                 if((buf_eth0[old+60] == 0x2e)&&(recv0 > 70))
                        {
                         buf_eth0[old+60] = 0x12;
                         buf_eth0[old+61] = 0x34;
                         buf_eth0[old+62] = 0x56;

                        printf("==========================\n");
                        printf("%d bytes read\n",recv0);
                        for(i=old+54;i<old+recv0;i++)
                                {
                                  printf(" %02x",buf_eth0[i]);
                                  if( (i+1-old-54) % 16 == 0)
                                        {
                                          printf("\n\n");                       
                                        }
                             
                                }
                         printf("\n\n");
                        }
                 recv0 = 0;
                 sem_post(&sem0);
                }
         else
                {
                 sem_post(&sem2);
                }
               
        }

return (void*)0;
}

void *send_eth0(void* attr)
{
  int *sockid;
  int sem,send0;
  sockid = (int*)attr;
  while(1)
        {
        /*sem = sem_trywait(&sem1);
        if(sem == 0)
                {       
                //send0 = send(*sockid,&buf_eth1[lenth1],num1,0);
                send0 = sendto(*sockid,&buf_eth1[lenth1],num1,0,(struct sockaddr *)&ether0,sizeof(ether0));
                 //send0 = send(*sockid,buf_eth1,num1,0);
                }
        else
                {
                 continue;
                }
        sem_post(&sem3);*/
         sem_wait(&sem1);
               
         send0 = send(*sockid,&buf_eth1[lenth1],num1,0);
        //send0 = sendto(*sockid,&buf_eth1[lenth1],num1,0,(struct sockaddr *)&ether0,sizeof(ether0));
         
        sem_post(&sem3);
         
        }
return (void*)0;
}


void *recv_eth1(void* attr)
{
int *sockid;
int ret=0,recv1,r;
struct ethhdr *eth;
struct iphdr *iph;
sockid = (int*)attr;
char *px;
while(1)
        {
         sem_wait(&sem3);
         if(MAX - ret <100)
                {
                 ret = 0;
                }
         recv1 = recv(*sockid,&buf_eth1[ret],MAX-ret,0);
         
         if(recv1 == 0)
                {
                 sem_post(&sem3);
                 continue;
                }
       
         px = &buf_eth1[ret];
         eth = (struct ethhdr*)px;
         iph = (struct iphdr*)(px+sizeof(struct ethhdr));
         char *s1 = inet_ntoa(*(struct in_addr *)&iph->daddr);
         char *s2 = "192.168.1.77";
         r = strcmp(s1,s2);
         if((r == 0)||(iph->protocol > 100))
                {
                  
                       lenth1 = ret;          
                   num1 = recv1;
                   ret = ret + recv1;
                  recv1 = 0;
                  sem_post(&sem1);
                }
         else
                {
                 sem_post(&sem3);
                }
               
         /*recv1 = recv(*sockid,buf_eth1,MAX,0);
         num1 = recv1;
         sem_post(&sem1);*/

        }

return (void*)0;
}

void *send_eth1(void* attr)
{
  int *sockid;
  int sem,send1,sendnum;
  sockid = (int*)attr;
  while(1)
        {
        /*sem = sem_trywait(&sem0);
        if(sem == 0)
                {       
                //send1 = send(*sockid,&buf_eth0[lenth0],num0,0);
                send1 = sendto(*sockid,&buf_eth0[lenth0],num0,0,(struct sockaddr *)&ether1,sizeof(ether1));
                 //send1 = send(*sockid,buf_eth0,num0,0);
                }
        else
                {
                 continue;
                }
         sem_post(&sem2);*/

         sem_wait(&sem0);
         
         //send1 = sendto(*sockid,&buf_eth0[lenth0],num0,0,(struct sockaddr *)&ether1,sizeof(ether1));       
         send1 = send(*sockid,&buf_eth0[lenth0],num0,0);
         sem_post(&sem2);
        }
return (void*)0;
}



int main()
{
pthread_t thd0,thd1,thd2,thd3;
int ret,sock_recv0,sock_send0,sock_recv1,sock_send1,bindid;
struct ifreq ifr0,ifr1;
struct sockaddr_ll ether0,ether1;
int *attr;
ret = sem_init(&sem0,0,0);
ret = sem_init(&sem1,0,0);
ret = sem_init(&sem2,0,1);
ret = sem_init(&sem3,0,1);
                               /*Creat socks*/


/*eth0 recv sock*/
sock_recv0 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_recv0 < 0)
        {
         printf("Creat eth0 receive socket error\n");
        }
else
        {
         printf("eth0 receive socket created\n");
        }
bzero(&ether0,sizeof(ether0));
strcpy(ifr0.ifr_name,"eth0");
ether0.sll_family = PF_PACKET;
ioctl(sock_recv0,SIOCGIFINDEX,&ifr0);
ether0.sll_ifindex = ifr0.ifr_ifindex;
ether0.sll_protocol = htons(ETH_P_ALL);
bindid = bind(sock_recv0,(struct sockaddr_ll*)&ether0,sizeof(struct sockaddr_ll));
  if(bindid < 0)
        {
         printf("Bind recv socket failed\n");
         printf("%d\n",bindid);
        }
  else
        {
          printf("Bind recv sock to eth0 success\n");
        }
/*eth0 send sock*/
sock_send0 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_send0 < 0)
        {
         printf("Creat eth0 send socket error!\n");
        }
else
        {
         printf("eth0 send socket created\n");
        }
  ioctl(sock_send0,SIOCGIFINDEX,&ifr0);
  ether0.sll_ifindex = ifr0.ifr_ifindex;
  bindid = bind(sock_send0,(struct sockaddr_ll*)&ether0,sizeof(struct sockaddr_ll));
  if(bindid < 0)
         {
          printf("Bind send socket failed\n");
          printf("%d\n",bindid);
         }
  else
         {
          printf("Bind send sock to eth0 success\n");
         }
/*eth1 recv sock*/
sock_recv1 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_recv1 < 0)
        {
         printf("Creat eth1 receive socket error\n");
        }
else
        {
         printf("eth1 receive socket created\n");
        }
  //x = fcntl(sock_recv1,F_GETFL,0);
  //fcntl(sock_recv1,F_SETFL,x|O_NONBLOCK);
bzero(&ifr1,sizeof(ifr1));
bzero(&ether1,sizeof(ether1));
strcpy(ifr1.ifr_name,"eth1");
ether1.sll_family = PF_PACKET;
ioctl(sock_recv1,SIOCGIFINDEX,&ifr1); //get eth1 index
ether1.sll_ifindex = ifr1.ifr_ifindex;
ether1.sll_protocol = htons(ETH_P_ALL);

bindid = bind(sock_recv1,(struct sockaddr_ll*)&ether1,sizeof(struct sockaddr_ll));
if(bindid < 0)
         {
          printf("Bind recv socket failed\n");
          printf("%d\n",bindid);
        }
else
        {
          printf("Bind recv sock to eth1 success\n");
        }
/*eth1 send sock*/
sock_send1 = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_send1 < 0)
        {
          printf("Creat eth1 send socket error!\n");
        }
else
        {
         printf("eth1 send socket created\n");
        }
  ioctl(sock_send1,SIOCGIFINDEX,&ifr1); //get eth1 index
  ether1.sll_ifindex = ifr1.ifr_ifindex;
  bindid = bind(sock_send1,(struct sockaddr_ll*)&ether1,sizeof(struct sockaddr_ll));
if(bindid < 0)
         {
          printf("Bind send socket failed\n");
          printf("%d\n",bindid);
         }
else
         {
          printf("Bind send sock to eth1 success\n");
         }



                          /*Creat pthreads*/
attr = &sock_recv0;
ret  = pthread_create(&thd0,NULL,(void*)recv_eth0,(void*)attr);
if(ret)
        {
         printf("Creat pthread_eth0 error\n");
         exit(0);
        }
attr = &sock_send0;
ret  = pthread_create(&thd1,NULL,(void*)send_eth0,(void*)attr);
if(ret)
        {
         printf("Creat pthread_eth0 error\n");
         exit(0);
        }
attr = &sock_recv1;
ret  = pthread_create(&thd2,NULL,(void*)recv_eth1,(void*)attr);
if(ret)
        {
         printf("Creat pthread_eth0 error\n");
         exit(0);
        }
attr = &sock_send1;
ret  = pthread_create(&thd3,NULL,(void*)send_eth1,(void*)attr);
if(ret)
        {
         printf("Creat pthread_eth0 error\n");
         exit(0);
        }
//while(1);
pthread_join(thd3,NULL);

return 0;
}

论坛徽章:
0
2 [报告]
发表于 2013-07-03 11:32 |只看该作者
这也太长了吧,看得眼都疼……

论坛徽章:
0
3 [报告]
发表于 2013-07-05 15:21 |只看该作者
回复 2# 卖萌犯法


   

论坛徽章:
0
4 [报告]
发表于 2013-07-05 15:23 |只看该作者
回复 2# 卖萌犯法


    我错了。。。那个如果我改了TCP报文数据段的内容,TCP报头那里的校验和要不要改?以太网帧最后四位的CRC校验码要不要改?

论坛徽章:
0
5 [报告]
发表于 2013-07-07 01:27 |只看该作者
回复 4# xmcxguo

TCP报头那里的校验和要不要改

要重新计算

以太网帧最后四位的CRC校验码要不要改

用户空间的程序不需要关心CRC,它由网卡驱动计算
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP