#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <string> #include <iostream> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <time.h> #include <netinet/tcp.h> void client(int fd,std::string server_ip,short server_port,double bandwidth); int send_block(int fd,const char *buf,size_t buf_len); int main(int n,char *arg[]) { if(4!=n) { fprintf(stderr,"usage: ./client + server ip + port + bandwidth\n"); return -1; } std::string server_ip=std::string(arg[1]); short server_port=static_cast<short>(atoi(arg[2])); double bandwidth=atof(arg[3]); int client_sockfd; if(-1!=(client_sockfd=socket(AF_INET,SOCK_STREAM,0))) { client(client_sockfd,server_ip,server_port,bandwidth); close(client_sockfd); } else { fprintf(stderr,"%s\n",strerror(errno)); return -1; } return 0; } void client(int fd,std::string server_ip,short server_port,double bandwidth) { int no_delay=1; if(-1==setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(const char *)&no_delay,sizeof(int))) { fprintf(stderr,"%s\n",strerror(errno)); return; } int send_buf=1024*32; if(-1==setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const char *)&send_buf,sizeof(int))) { fprintf(stderr,"%s\n",strerror(errno)); return; } struct sockaddr_in server_addr; memset(&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=inet_addr(server_ip.c_str()); server_addr.sin_port=htons(server_port); if(-1==connect(fd,(const sockaddr *)&server_addr,sizeof(struct sockaddr))) { fprintf(stderr,"%s\n",strerror(errno)); return; } std::string data; data+="RTSP/1.0 200 OK\r\n"; data+="CSeq: 312\r\n"; data+="Date: 23 Jan 1997 15:35:06 GMT\r\n"; data+="Content-Type: application/sdp\r\n"; data+="Content-Length: 365\r\n\r\n"; data+="v=0\r\n"; data+="o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4\r\n"; data+="s=SDP Seminar\r\n"; data+="i=A Seminar on the session description protocol\r\n"; data+="u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps\r\n"; data+="e=mjh@isi.edu (Mark Handley)\r\n"; data+="c=IN IP4 224.2.17.12/127\r\n"; data+="t=2873397496 2873404696\r\n"; data+="a=recvonly\r\n"; data+="m=audio 3456 RTP/AVP 0\r\n"; data+="m=video 2232 RTP/AVP 31\r\n"; data+="m=whiteboard 32416 UDP WB\r\n"; data+="a=orient:portrait\r\n\r\n"; //adjust data size for(int i=0;i<4;++i) { data+=data; } const int send_num=1200; unsigned int send_bytes=0; int r; double rate; unsigned int start_time=clock(); for(int i=0;i<send_num;++i) { if(-1==(r=send_block(fd,data.c_str(),data.size()))) { break; } else { send_bytes+=r; rate=send_bytes*1.0/((clock()-start_time)*1.0/CLOCKS_PER_SEC); while(rate>bandwidth*1024*1024) { rate=send_bytes*1.0/((clock()-start_time)*1.0/CLOCKS_PER_SEC); } } } unsigned int end_time=clock(); unsigned int time_elapse=end_time-start_time; std::cerr<<"data size= "<<data.size()<<" bytes"<<std::endl; std::cerr<<"total= "<<data.size()*send_num<<" bytes"<<std::endl; std::cerr<<"send= "<<send_bytes<<" bytes"<<std::endl; std::cerr<<"elapse= "<<(time_elapse*1.0/CLOCKS_PER_SEC)<<" s"<<std::endl; std::cerr<<"rate= "<<send_bytes*1.0/1024/(time_elapse*1.0/CLOCKS_PER_SEC)<<" KBps"<<std::endl; } int send_block(int fd,const char *buf,size_t buf_len) { if(buf_len<=0) { return -1; } unsigned int index=0; unsigned int send_len=0; int r; while(send_len<buf_len) { if(-1==(r=send(fd,buf+index,buf_len-send_len,0))) { if(errno==EAGAIN || errno==EWOULDBLOCK || errno==EINTR) { continue; } else { fprintf(stderr,"%s\n",strerror(errno)); return -1; } } else { index+=r; send_len+=r; } } return send_len; }