- 论坛徽章:
- 0
|
跪求!!!!各位大侠,帮帮忙,这个问题我查了很长时间了,现在我大致知道问题出在哪里,可能是我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;
} |
|