免费注册 查看新帖 |

Chinaunix

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

linux下网络编程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-27 15:39 |只看该作者 |倒序浏览
跪求!!!!各位大侠,帮帮忙,这个问题我查了很长时间了,现在我大致知道问题出在哪里,可能是我main()函数里面的申请内存的问题。先说一下,因为我客户端的程序比较长,所以我就不在这里贴出来了,我只贴相关部分的。服务器端代码都有。问题如下:我使用客户端给服务器传送一个结构体,然后在服务器端用多线程对这个结构体进行处理,所以我在服务器端的main函数里面动态的申请内存,然后把这个指针传出去,但是我发现有问题,然后我就改在main函数里面申请指针然后再释放指针,发现有问题了。程序能够运行,有时运行几秒,有时运行几分钟,然后都是在服务器端出现segmention fault。请好心人帮帮忙,我已经花了很长时间在上面了。
服务器端代码
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<sys/wait.h>
typedef  unsigned char  u8_t ;
typedef  unsigned short u16_t ;
typedef  unsigned int         u32_t ;
typedef  unsigned long long u64_t ;


int serv_port=9999;
typedef struct __ether_header_t {
//#define     ZERO_DATA_RESERVE_LEN       2
//   u8_t    reserve[ZERO_DATA_RESERVE_LEN] ;
    u8_t    dmac[6];
    u8_t    smac[6];
    u16_t   ether_type;
  }ether_header_t;
  
typedef struct _ip_header_t{
#if defined(__LITTLE_ENDIAN_BITFIELD)
    u8_t    ihl:4, version:4;
#else defined (__BIG_ENDIAN_BITFIELD)
    u8_t    version:4, ihl:4;
#endif
    u8_t    tos;
    u16_t   tot_len;
    u16_t   id;
    u16_t   frag_off;
    u8_t    ttl;
    u8_t    protocol;
    u16_t   check;
    u32_t   saddr;
    u32_t   daddr;
}ip_header_t;
typedef struct _sock_packet_info{
    struct timeval stamp;
    //recieved packet length
    unsigned short  pkt_len;
#define     ZERO_MAX_RESERVE_DATA_LEN   2028
    unsigned char   data [ZERO_MAX_RESERVE_DATA_LEN];
}sock_packet_info_t;
int _tcp_listen(unsigned short serv_port){
        int sockfd;
        int addrlen = sizeof(struct sockaddr_in);
        struct sockaddr_in servaddr;

int on=1;

        if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0){                //create socket
                printf("socket() failed, return...\n");
                return -1;
        }
printf("socket success\n");
setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

        bzero(&servaddr, sizeof(servaddr));                                //server's address
        servaddr.sin_family = PF_INET;
        servaddr.sin_port = htons(serv_port);
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
                                                                                       
        if(bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){        //bind to server's address
                printf("bind() failed, return...\n");
                return -1;
        }
       
        if(listen(sockfd, 10) < 0)                                        //create listenning queue
        {
                printf("listen() failed, return...\n");
                return -1;
        }

        printf("Waiting for data on port TCP %u\n", serv_port);

        return sockfd;       
}


int _tcp_accept(int sockfd){
        int newfd;
        int addrlen = sizeof(struct sockaddr_in);
        struct sockaddr_in clientaddr;
       
        if((newfd = accept(sockfd, (struct sockaddr*)&clientaddr, &addrlen)) < 0)
        {
                printf("accept() failed, /////return...\n");
                return -1;
        }

        return newfd;
}



int _tcp_recv(int sockfd, char *buf, int buf_len){
        int msg_len;
       
        msg_len = recv(sockfd, buf, buf_len, 0);
        if( msg_len < 0 )
        {
                printf("recv() failed, return...\n");
                return -1;
        }

        printf("Received message length from tcp is: %d\n", msg_len);

        return msg_len;
}



int        main(int argc,char *argv[])
{


int client_fd;
int serv_fd;

int ret;
pid_t pid;
//struct sockaddr_in client_addr;
int client_len;
int msglen,buf_len;
u_char buf[2040];//这里要定义大小。很重要(搞了好几天,一定要注意大小)
sock_packet_info_t *pPacket,*ppkt;
ip_header_t *pheader;

struct in_addr  in;

   serv_fd=_tcp_listen(serv_port);
if(serv_fd<0)
        {
                exit(1);
        }
client_fd=_tcp_accept(serv_fd);
if(client_fd<0)
{
close(serv_fd);
exit(2);
}
while ( 1 )
{
        msglen=_tcp_recv(client_fd,buf,sizeof(buf));
        if(msglen<0)
                exit(1);
  
   if(msglen==0)
  {
    close(client_fd);
    break;
   }
//  buf[msglen]='\0';

         pPacket=(sock_packet_info_t *)malloc(sizeof(sock_packet_info_t ));   
         ppkt=(sock_packet_info_t *)buf;
  pPacket->stamp.tv_sec=ppkt->stamp.tv_sec;  
  pPacket->stamp.tv_usec=ppkt->stamp.tv_usec;  
                pPacket->pkt_len=ppkt->pkt_len;
        memcpy(pPacket->data,ppkt->data,ppkt->pkt_len);
printf("time:%u\n",pPacket->stamp.tv_sec);
                //debug("get a packet %d %d \n", SRCPORT(pPacket->data+16), DSTPORT(pPacket->data+16));
        pheader=(ip_header_t *)(pPacket->data+14);
//pheader=(ip_header_t *)(buf);
printf("addr:%u,\n",ntohl(pheader->saddr));
printf("protocol: %d\n",pheader->protocol);
free(pPacket);



}

        return 0 ;
}


客户端部分代码

void dispose_packet(u_char *p,const struct pcap_pkthdr *header,const u_char *packet_content)
{
  tcp_flags=0;
        struct ether_header *ether_protocol;
        struct ip_header *ip_protocol;
        struct tcp_header *tcp_protocol;
        struct udp_header *udp_protocol;
     sock_packet_info_t *pPacket;
        unsigned short ether_type;
        PACKET pkt_header;
         int size_ip;
        int size_tcp;
        u_char buf[100];
        int len;
struct  in_addr in;
        ether_protocol=(struct ether_header *)(packet_content);
        ether_type=ntohs(ether_protocol->ether_type);
        if(ether_type!=0x800)//不是ip协议就返回,我们处理的tcp、udp、ICMP的包头都是IP
                return;
        ip_protocol=(struct ip_header *)(packet_content+14);
        size_ip=ip_protocol->ip_header_length*4;
        if(size_ip<20)
        {
                printf("Invalid IP header length");
            return;
        }
   pkt_header.Timestamp.tv_sec=header->ts.tv_sec;
   pkt_header.Timestamp.tv_usec=header->ts.tv_usec;
   pkt_header.SIP=ntohl(ip_protocol->ip_source_addr);
   pkt_header.DIP=ntohl(ip_protocol->ip_destination_addr);
   pkt_header.Proto=ip_protocol->ip_protocol;

if(ip_protocol->ip_protocol==6)//协议为TCP
        {
                tcp_protocol=(struct tcp_header *)(packet_content+14+size_ip);
        pkt_header.SPort=ntohs(tcp_protocol->tcp_source_port);
               
        pkt_header.DPort=ntohs(tcp_protocol->tcp_destination_port);
        tcp_flags=tcp_protocol->tcp_flags;
                // printf("tcp_flags:%d\n",tcp_flags);

        }
        if(ip_protocol->ip_protocol==17)
        {
                udp_protocol=(struct udp_header *)(packet_content+14+size_ip);
                pkt_header.SPort=ntohs(udp_protocol->udp_source_port);
        pkt_header.DPort=ntohs(udp_protocol->udp_destination_port);
        }




        int decision=0;
if(RPS(&pkt_header)==1)
decision=1;
if(FSH(&pkt_header)==1)
decision=1;
if(Protos_flags(&pkt_header))
decision=1;
else if(FFS(&pkt_header))
decision=1;

if(decision)
{
pPacket=(sock_packet_info_t *)malloc(sizeof(sock_packet_info_t));
               
pPacket->stamp.tv_sec=header->ts.tv_sec;

pPacket->stamp.tv_usec=header->ts.tv_usec;

pPacket->pkt_len=ntohs(ip_protocol->ip_lenth);

printf("ntohs(ip_protocol->ip_lenth):%d\n",ntohs(ip_protocol->ip_lenth));
memcpy(pPacket->data,packet_content,ntohs(ip_protocol->ip_lenth));

printf("connected ok\n");
printf("time:%u\n",pPacket->stamp.tv_sec);
        ip_protocol=(struct ip_header *)(pPacket->data+14);
printf("sddr:%u\n",ntohl(ip_protocol->ip_source_addr));
in.s_addr=ip_protocol->ip_source_addr;
        printf("soucrce addr:%s\n",inet_ntoa(in));

len=_tcp_send(sockfd,pPacket,sizeof(sock_packet_info_t));

//len=_tcp_send(sockfd,packet_content,ntohs(ip_protocol->ip_lenth));

        if(len<0)
                {exit(1);
                }
printf("send to monster\n");

free(pPacket);
}



}

int  main()
{       
   int i=0;

        char *dev = NULL;
//        char *filter_exp = NULL;
        char errbuf[PCAP_ERRBUF_SIZE];
        bpf_u_int32 mask;
        bpf_u_int32 net;
        pcap_t *handle;       
        struct itimerval value;
        int num_packets = 2000;       
//        struct bpf_program fp;




srand(time(0));
dev ="eth1";
        if (pcap_lookupnet(dev,&net, &mask, errbuf) == -1)
        {
                fprintf(stderr, "Can't get netmask for device %s\n", dev);
                net = 0;
                mask = 0;
        }
        handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
        if (handle == NULL)
        {
                fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
                return(2);
        }

        if((sockfd=_tcp_connect(9999,"127.0.0.1"))<0)
                {
              exit(2);
                }
    while(1)
     {

     pcap_loop(handle,1,dispose_packet,NULL);
    i++;
     }


     printf("sucess");
return 0;
}

论坛徽章:
0
2 [报告]
发表于 2010-05-27 17:25 |只看该作者
buf 可能是它的问题将

由于你没有动态
free(pPacket)后
将他搞成"0";
memset(buf,0,sizeof(buf));
pPacket = NULL;

程序上应该没有什么问题;

论坛徽章:
0
3 [报告]
发表于 2010-05-28 22:33 |只看该作者
回复 2# awe4


    不行呀,我加了之后,运行了10分钟,然后又是segmention fault,

论坛徽章:
0
4 [报告]
发表于 2010-05-31 15:54 |只看该作者
还怀疑是:u_char buf[2040];的问题你数一下字节数你强转之后
在有可能由于编译器对齐(4字节对齐)这个结构就是2050
sock_packet_info_t 大小应该是/*2048*/
{
    struct timeval stamp; /*8*/
    //recieved packet length
    unsigned short  pkt_len;/*2*/
        #define     ZERO_MAX_RESERVE_DATA_LEN   2028
    unsigned char   data [ZERO_MAX_RESERVE_DATA_LEN];
}

建议不要这样用哦
直接这样搞吧:
ppkt =  (sock_packet_info_t*)malloc(sizeof(struct sock_packet_info_t));
直接用他也不错.
你自己调试一下啊.各个地方+打印看看哪里segment 了

论坛徽章:
0
5 [报告]
发表于 2010-05-31 17:21 |只看该作者
代码太乱了。。。看不下去
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP