📄 tcpclient.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 + -