精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
1、开发平台Linux,gcc编译
2、客户端用十个线程往服务器发数据包,每包1000字节,每隔一秒发一千个包,服务端每隔3秒打印一次抓包结果,显示丢包情况。
3、所涉技术:UDP方式socket使用,多线程程序设计,socket高级处理属性设置,Linux线程函数
核心代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <pthread.h>
#define SLPTM 3//打印输出间隔时间
void *output();
struct timeval tv;
struct timezone tz;
long count=0;
int main(void)
{
int listensd,n,rct;
pthread_t tid;
char recvbagbuf[1000];
struct sockaddr_in server_addr, clent_addr;
int cltaddrlen=sizeof(struct sockaddr_in);
int setoptvar=60000,yesno=1,setoptlen=sizeof(int);
int getoptvar,getoptlen=sizeof(int);
memset(recvbagbuf,0,sizeof(recvbagbuf));
listensd=socket(AF_INET,SOCK_DGRAM,0);
setsockopt(listensd,SOL_SOCKET,SO_REUSEADDR,&yesno,sizeof(yesno));//地址重用设置
getsockopt(listensd,SOL_SOCKET,SO_RCVBUF,&getoptvar,&getoptlen);
printf("RCVBUFoptvar is:%d,optlen is:%d\n",getoptvar,getoptlen);
setsockopt(listensd,SOL_SOCKET,SO_RCVBUF,&setoptvar,setoptlen);//改变socket缓冲大小
getsockopt(listensd,SOL_SOCKET,SO_RCVBUF,&getoptvar,&getoptlen);
printf("after RCVBUFoptvar is:%d,optlen is:%d\n",getoptvar,getoptlen);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(6300);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&server_addr.sin_zero,sizeof(server_addr.sin_zero));
bind(listensd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr_in));
rct=pthread_create(&tid,NULL,(void*)output,NULL);//创建打印输出线程
if(rct != 0){
perror("ThreadCreate Failed!\n");
exit(1);
}
while(1){
recvfrom(listensd,recvbagbuf,1000,0,
(struct sockaddr*)&clent_addr,&cltaddrlen);
count++;
}
close(listensd);
return 0;
}
void*output()
{
while(1){
long cnt1,cnt2;
cnt1=count;
sleep(SLPTM);
cnt2=count;
printf("BagsTotel:%d\ntime:%dS bags:%d\n",count,SLPTM,cnt2-cnt1);
printf("agv:%d(bags/S)\n",(cnt2-cnt1)/SLPTM);
printf("lost %f%\n",(1.0-(float)(cnt2-cnt1)/SLPTM/(float)10000)*100);//统计丢包率,一定注意类型的转换
}
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <pthread.h>
void *sendbagthread();
int main(void)
{
int i, rect;
pthread_t tid[10];
for(i=0;i<10;i++){
rect=pthread_create(&tid[i],NULL,(void*)sendbagthread,NULL);//创建十个发包线程
if(rect != 0){
perror("ThreadCreate Failed!\n");
exit(1);
}
printf("i=%d creat thread:%d scuess!\n",i,tid[i]);
}
for(i=0;i<10;i++)
pthread_join(tid[i], NULL);
return 0;
}
void *sendbagthread()
{
struct sockaddr_in server_addr;
int socksd,i;
char bag[1000];
memset(bag,'$',sizeof(bag));
printf("entered this thread!\n");
socksd=socket(AF_INET,SOCK_DGRAM,0);
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
server_addr.sin_port=htons(6300);
bzero(&server_addr.sin_zero,sizeof(server_addr.sin_zero));
while(1){
for(i=0;i<1000;i++)
sendto(socksd,bag,sizeof(bag),0,
(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in));
sleep(1);
}
close(socksd);
pthread_exit(NULL);
}