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

📄 tcpclient.c

📁 支持平滑的带宽控制及统计,包括linux的测试程序
💻 C
字号:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
#include <signal.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>


#define	SERVER_PORT	2001

#define	MAX_LEN		1024

#define BWCALC_SML      256

#define	MAX_BW		(64<<20)

typedef	long long 	longlong;

typedef struct  _bwcontrol_info{
        longlong	x0;
        unsigned long  	y0;
        unsigned long   maxbw;
        unsigned long   minbw;
	unsigned long	rate;
}bwcontrol_info,*pbwcontrol_info;


longlong gettickcount();

unsigned long bwctl_getcurrate(bwcontrol_info *pbw);

int bwctl_filter(bwcontrol_info *pbw,unsigned short len,int bmax);


typedef	struct	_client_info{
	int	state;
	int	socket;
}client_info,*pclient_info;

static	int	client_init(unsigned long srcip,unsigned long dstip);

static	void	client_close();

static	int	client_recv();

static	void	sig_usr(int signo);

static	unsigned long sip=0x2201a8c0;

static  unsigned long dip=0x2101a8c0;

static	client_info	ci;

static	int		done=0;

static	bwcontrol_info	bi;

static	void	usage();

int	main(int argc,char *argv[])
{
	
	longlong t1=gettickcount();
  	sigset_t sig,sigsave;	
	if(argc == 1){
		sip=0x0100007F;
		dip=0x0100007F;
	}
	else if(argc == 2){
		sip=inet_addr(argv[1]);
		dip=inet_addr(argv[1]);
		if((sip == 0xffffffff)||(dip == 0xffffffff)){
			usage();
			return	0;
		}
	}
	else if(argc == 3){
		sip=inet_addr(argv[2]);
		dip=inet_addr(argv[1]);
		if((sip == 0xffffffff)||(dip == 0xffffffff)){
			usage();
			return	0;
		}
	}
	else{
		usage();
		return	0;
	}
	usage(); 
	signal(SIGUSR1,sig_usr);
	signal(SIGUSR2,sig_usr);
/*	
        sigemptyset(&sig);
	sigaddset(&sig,SIGINT);
	sigaddset(&sig,SIGTSTP);
	sigprocmask(SIG_BLOCK,&sig,&sigsave);
*/	
	bi.maxbw=MAX_BW;
	while(1){
		if(done==1)
			break;
		if((gettickcount()-t1)>1000){
			printf("\nrate=%d kbps",bwctl_getcurrate(&bi)>>10);
			t1=gettickcount();
		}
		client_init(sip,dip);
		if(!ci.state){
			sleep(2);
		}
		else{
			client_recv();
		}
		
	}
	client_close();
//	sigprocmask(SIG_SETMASK,&sigsave,NULL);
	return	0;
}

void	usage()
{
	printf("\ntcpclient usage:");
	printf("\n\ttcpclient [destip] [sourceip]");
	printf("\n\tif no para,default destip=sourceip=127.0.0.1");
	printf("\n\tif one para ipstr, destip=sourceip=ipstr");
	printf("\n\tif two para ipstr1 ipstr2, destip=ipstr1 and sourceip=ipstr2");
	printf("\n\n");
}



int	client_init(unsigned long srcip,unsigned long dstip)
{
        struct sockaddr_in myaddr;
	struct sockaddr_in opaddr;      
        struct timeval tval;	  
        fd_set set;
        int val,fd,r;
	if(ci.state)
		return	1;
       	fd=socket(AF_INET,SOCK_STREAM,0);
        if(fd<0)
                return 0;
        myaddr.sin_family=AF_INET;
        myaddr.sin_port=0;
        myaddr.sin_addr.s_addr=srcip;
        if(bind(fd,(struct sockaddr *)&myaddr,sizeof(myaddr))==-1){
                close(fd);
                return 0;
        }
        opaddr.sin_family=AF_INET;
        opaddr.sin_port=htons(SERVER_PORT);
        opaddr.sin_addr.s_addr=dstip;
ci1:
        r=connect(fd,(struct sockaddr *)&opaddr,sizeof(opaddr));
        if(r<0){
        	printf("\nclient start erred");
        	close(fd);
        	return	0;
        }
        val=fcntl(fd,F_GETFL,0);
        fcntl(fd,F_SETFL,val|O_NONBLOCK);
	r=1;
	setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&r,sizeof(int));
	printf("\nclient started");
	ci.socket=fd;
	ci.state=1;
        return 1;	
}

void	client_close()
{
	if(ci.state==0)
		return;
	close(ci.socket);
	ci.state=0;
	printf("\nclient stopped\n");
}

int	client_recv()
{
	int 	len;
	char 	recvbuf[MAX_LEN];
	unsigned short	recved=0;
	while(1){
cr1:
		len=recv(ci.socket,recvbuf+recved,MAX_LEN-recved,0);
		if(len<0){
			if(errno==EINTR)
				goto cr1;
			if(errno==EWOULDBLOCK){
				usleep(20);
				continue;
			}
			client_close();
			return	0;
		}
		if(len==0){
			client_close();
			return 0;
		}
		bwctl_filter(&bi,len,1);
		recved+=len;
		if(recved==MAX_LEN){
			recved=0;
			return	0;
		}
	}
}

unsigned long   bwctl_getcurrate(bwcontrol_info *pbi)
{
        longlong tick=gettickcount()-pbi->x0;
        if(tick>(BWCALC_SML<<1))return 0;
	return pbi->rate;	
}
                                                                                                                                                                       
int bwctl_filter(bwcontrol_info *pbi,unsigned short len,int bmax)
{
	longlong ll;
        longlong tick=gettickcount();
        if((pbi->y0+(len<<3))> (((bmax?pbi->maxbw:pbi->minbw)/1000)*(tick-pbi->x0)))
                return 0;
        pbi->y0+=(len<<3);
        ll=(longlong)pbi->y0;
        pbi->rate=(unsigned long)(ll*1000/(tick-pbi->x0));
        if((tick-pbi->x0) > BWCALC_SML){
                pbi->y0=pbi->y0*(BWCALC_SML>>1)/(tick-pbi->x0);
                pbi->x0=tick-(BWCALC_SML>>1);
        }
        return 1;
}
                                                                                                                                                                       
longlong gettickcount()
{
        struct timeb tp;
        ftime(&tp);
        return ((longlong)tp.time)*1000+tp.millitm;
}


void	sig_usr(int signo)
{
	if((signo==SIGUSR1)||(signo==SIGUSR2)){
		printf("\nrecved user signal");
		done=1;
	}
}

⌨️ 快捷键说明

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