⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gap_b3.cpp

📁 这是一本学习 window编程的很好的参考教材
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*  
gcc -Wall -g `libnet-config --defines` gap.c -o gap `libnet-config --libs` -pthread -lpcap
gcc -DDEBUG -Wall -g `libnet-config --defines` gap.c -o gap `libnet-config --libs` -pthread -lpcap
*/

/*-------------------------------------------------------------
04-04-21  每次发送超时时,都发送一个ack.防止ack丢失

--------------------------------------------------------------*/
#include "stdafx.h"


#include "gap_b3.h"

#define LIBNET_ERRBUF_SIZE 0x100
//#define dbg_log 0

void dbg_log( char *fmt, ... ) 
{
	va_list	arg;
	char	line[ 2048 ];
	
	va_start( arg, fmt );
	vsnprintf( line, sizeof( line ), fmt, arg );
	va_end( arg );
	
	//dbg_log( "%s\n", line);
	OutputDebugString(line);
	
}

void do_kill( HANDLE thread_id )
{
	if( thread_id != recv_id )
	{
		dbg_log( "cancle recv thread\n");
		TerminateThread (recv_id,0 );
	}
	if( thread_id != send_id )
	{
		dbg_log( "cancle send thread\n");
		TerminateThread (send_id ,0);
	}
	if( thread_id != output_id )
	{
		dbg_log( "cancle output thread\n");
		TerminateThread (output_id,0 );
	}
	if( thread_id != input_id )
	{
		dbg_log( "cancle input thread\n");
		TerminateThread (input_id ,0);
	}
	
	dbg_log( "exit my thread\n");
	
}

void init_param()
{

	GLBSTATE = BEGIN;

	srand( time( 0 ) );
	
	input_in = input_queue;
	input_out = input_queue;
	output_in = output_queue;
	output_out = output_queue;
	output_acked = output_queue;
	
	ack = 0;
	sentack = 0;
	acked = 0;
	sentid =0;
	my_window = QUEUE_LEN;
	opp_window = QUEUE_LEN;
	sentwindow = QUEUE_LEN;
	
	counter = 1;
	waitinginput = 0;
	waitingoutput = 0;
	waitingsend = 0;
	hellonum = 0;
	resendpackets = 0;

	

	memset( output_queue, '\0', sizeof( output_queue ) );
	memset( input_queue, '\0', sizeof( input_queue ) );
	InitializeCriticalSection(&lock_mywd);
	
	InitializeCriticalSection(&lock_output);
	InitializeCriticalSection(&lock_oppwd);
		
	InitializeCriticalSection(&lock_send);
	InitializeCriticalSection(&lock_input);
	input_ok=CreateEvent(NULL,TRUE,FALSE,"input_ok");	
	output_ok=CreateEvent(NULL,TRUE,FALSE,"output_ok");
	send_ok=CreateEvent(NULL,TRUE,FALSE,"send_ok");
	
}

void get_flag( char *buf, int len )
{
	unsigned short int	s ;
	char			*p;
	unsigned short int	random;
	int			m_len;
	
	random = ( unsigned short int )rand();
	
	p = buf + 2;
	*(unsigned short int *)p = random;
	m_len = len;

	s = ( random - SOURCE ) ^ SOURCE;
	p += 2;
	while( m_len > 1 )
	{
		s = *( unsigned short int *) p ^ s;
		p += 2 ;
		m_len -= 2;
	}
	
	if( m_len == 1 )
	   s = *p ^ s;
	
	*(unsigned short int *)buf = s ^ PASSWORD;
	
	return;
}

void hand(  pcap_t*   handle)
{
	Frame frame;
	
	dbg_log( "enter hand\n");
	for( ; GLBSTATE != FINISH || hellonum != 0;)
	{
		if( ( GLBSTATE & RECVRSP ) == 0 )
		{
			memset( ( char *)&frame, '\0', sizeof( Frame ) );
			frame.sign = HELLO;
			frame.no = myno;
			get_flag( ( char *)&frame, HEAD_LEN - FLAG_LEN );
			while( pcap_sendpacket( handle, 
				(BYTE*)&frame, MIN_LEN ) != 0 )Sleep( 10 );
			GLBSTATE = GLBSTATE | SENDHELLO;
			dbg_log( "send hello ok\n");
		}
		
		if( hellonum > 0 )
		{
			memset( ( char *)&frame, '\0', sizeof( Frame ) );
			frame.sign = RSP;
			frame.no = myno;
			get_flag( ( char *)&frame, HEAD_LEN - FLAG_LEN );
			while( pcap_sendpacket( handle, 
				(BYTE*)&frame, MIN_LEN ) != 0 )Sleep( 10 );
			GLBSTATE = GLBSTATE | SENDRSP;
			dbg_log( "send rsp ok\n");
			hellonum --;
		}
		Sleep( 500 );
	}
}


void Input_Thread( LPARAM lParam )
{
	int			size;
	unsigned short int	id;

	dbg_log( "enter cycle\n");
	for( ; ; )
	{		
		id = *(unsigned short int *)output_in->frame.id;		
		if( output_in -> state == EMPTY )
		{
			/* have empty place in output queue */
					memset( ( char *)&output_in->frame, '\0', sizeof( Frame ) );
					 ReadFile( inputfd, output_in->frame.data, DATA_LEN,(LPDWORD)&size,NULL );  /* 填充数据 */
					if( size < 0 )
					{
						dbg_log( "read file error or end of file!!!!!!\n" );
						break;
					}
					if( size ==0 )
					{
						output_in->frame.cFlag = 1;
						size = 100;
					}
					dbg_log( "read a packet, size: %d id= %d\n", size, counter);
					output_in -> state = NOSEND;
					output_in -> times = 0;
					*( unsigned short int *)output_in -> frame.id = counter++;
					*( unsigned short int *)output_in -> frame.length = size;
					output_in++;
					if( output_in == output_queue + QUEUE_LEN )output_in = output_queue;

					if( waitingsend == 1 )
					{				
						EnterCriticalSection( &lock_send );
						SetEvent(send_ok );
						LeaveCriticalSection( &lock_send );
					}
		} /* if */
		else
		//Sleep( 2000 );
		{
			EnterCriticalSection( &lock_input );
			
			waitinginput = 1;
			if( WaitForSingleObject(input_ok, TIMEOUT*1000) ==WAIT_TIMEOUT)
			{
				dbg_log( "input timeout. continue!\n");
				LeaveCriticalSection( &lock_input );
				waitinginput = 0;
				continue;
			}
			ResetEvent(input_ok);
			dbg_log( "have input message!\n");			
			LeaveCriticalSection( &lock_input );
			waitinginput = 0;
			continue;
		}
	}
	//EndSend();
}
void GetNetcardName(pcap_if_t *d,char* netchardsource )
{
	pcap_addr_t *a;



	for(a=d->addresses;a;a=a->next) {
		//printf("\tAddress Family: #%d\n",a->addr->sa_family);

		switch(a->addr->sa_family)
		{
		case AF_INET:
			/*printf("\tAddress Family Name: AF_INET\n");*/
			if (a->addr){
				_tcscpy(netchardsource,d->name);
			}
			break;



		default:

			break;
		}
	}

}



pcap_t* GetOpenLink(){

	pcap_if_t *alldevs;
	pcap_if_t *d;
	pcap_t* fp;
	char errbuf[PCAP_ERRBUF_SIZE+1];
	char netchardsource [1024];
	if (pcap_findalldevs_ex("rpcap://", NULL, &alldevs, errbuf) == -1)
	{
		MessageBox(NULL,"WinPCap程序加载失败,请重新运行安装程序安装WinPCap","提示",MB_OK|MB_ICONSTOP);
		return NULL ;
	}
	for(d=alldevs;d;d=d->next)
	{
		GetNetcardName(d,netchardsource);
	}


	if ( (fp= pcap_open(netchardsource/*"\\Device\\NPF_{8065DF3F-B15B-4EE1-BFEF-0A8893E9DABE}"*/,			// name of the device
		256,				// portion of the packet to capture (only the first 100 bytes)
		PCAP_OPENFLAG_PROMISCUOUS, 	// promiscuous mode
		1,				// read timeout
		NULL,				// authentication on the remote machine
		errbuf				// error buffer
		) ) == NULL)

	{
		ATLTRACE("\nUnable to open the adapter. %s is not supported by WinPcap\n",netchardsource);
		return NULL;
	}
	return fp;
}
void Send_Thread(  LPARAM lParam )
{
	char	err_buf[ LIBNET_ERRBUF_SIZE ];
	
	

	unsigned short int	packet_len, id, ackedtmp;
	Frame	*frm, ackframe;
	int	times;
	Queue	*tmp;
	int	i;
	pcap_t*  Lib_Handle=GetOpenLink();
	
	if( Lib_Handle == NULL )
	{
		//EndSend();
		dbg_log( "libnet_open_link_interface: %s\n", err_buf );
		return; 
	}
	
	/* do hand */
	hand( Lib_Handle);
	Sleep( 1000 );
	if( GLBSTATE == FINISH ) GLBSTATE = RUNNING;
	
	dbg_log( " -----------------init ok, start------------------------------ \n");
	for( ; ; )
	{
		ackedtmp = acked + 1;
		if( ackedtmp != 0 || output_acked != output_queue )
		{
			for( i = 0; i < QUEUE_LEN; i ++ )
			{
				dbg_log( " acked:%d   id:%d \n", ackedtmp, *(unsigned short int *)output_acked->frame.id);
				if( (output_acked == output_out) && output_acked->state != SENT )
					break;
				else if( *(unsigned short int *)output_acked->frame.id == ackedtmp )
					break;				
				else if( *(unsigned short int *)output_acked->frame.id == 
					(unsigned short)( ackedtmp - 1 ) )
				{
					output_acked->state = EMPTY;
					output_acked ++;
					if( output_acked == output_queue + QUEUE_LEN )
						output_acked = output_queue;
					
					if( waitinginput == 1 )
					{
						EnterCriticalSection( &lock_input );
						SetEvent(input_ok );
						LeaveCriticalSection( &lock_input );
					}
					
					break;
				}
				else
				{
					output_acked->state = EMPTY;
					output_acked ++;
					if( output_acked == output_queue + QUEUE_LEN )
						output_acked = output_queue;
					
					if( waitinginput == 1 )
					{
						EnterCriticalSection( &lock_input );
						SetEvent(input_ok );
						LeaveCriticalSection( &lock_input );
					}
				}
			}
		}
		
		if( output_out -> state == NOSEND && opp_window > MIN_WINDOW )
		{
			frm = &output_out -> frame;
			packet_len = HEAD_LEN + *( unsigned short int *)frm -> length;
			if( packet_len < MIN_LEN )packet_len = MIN_LEN;
			frm -> window = my_window;			
			*( unsigned short int *)frm -> ack = ack;
			frm -> no = myno;

			times = 0;
			get_flag( ( char *)frm, HEAD_LEN - FLAG_LEN );
			while( times < 3 )
			{
				if( pcap_sendpacket( Lib_Handle,
					( BYTE * )frm, packet_len) == 0 )
					break;
				Sleep( 10 );
				times ++;
			}

			if( times == 3 )
			{
				dbg_log( "send a packet three times, failed. restart now!\n" );
				do_kill( send_id );
			}
			dbg_log( "sendpacket my_window:%d  id:%d  ack:%d  length:%d  sign:%d opp_window:%d\n", 
				frm -> window, *( unsigned short int *)frm -> id, *( unsigned short int *)frm -> ack,
				*( unsigned short int *)frm -> length, frm -> sign, opp_window - 1);
			
			sentid = *( unsigned short int *)frm -> id;
			EnterCriticalSection( &lock_oppwd );
			opp_window --;
			LeaveCriticalSection( &lock_oppwd );
			
			output_out -> state = SENT;
			EnterCriticalSection( &lock_output );
			output_out++;
			if( output_out == output_queue + QUEUE_LEN )output_out = output_queue;
			LeaveCriticalSection( &lock_output );

			sentack = ack;
			sentwindow = my_window;
		}
		else if( sentack != ack || sentwindow != my_window )
		{
			/* send ack and window only */
			memset( ( char *)&ackframe, '\0', sizeof( Frame ) );
			*( unsigned short int *)ackframe.id = 0;
			ackframe.window = my_window;
			*( unsigned short int *)ackframe.ack = ack;
			*( unsigned short int *)ackframe.length = 0;
			ackframe.no = myno;
			get_flag( ( char *)&ackframe, HEAD_LEN - FLAG_LEN );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -