Windows下丢包率测试源码

PacketLossTestClient:

PacketLossTestClient.cpp:
// PacketLossTestClient.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"

#include "SocketFrame.h"
int udp_client_fun_packetloss(int times, SOCKET s);
#define ECHOPORT "7210"
int main(int argc, char* argv[])
{
	CSocketFrame frame;
	int iResult;
	SOCKET ClientSocket;
	sockaddr_in servaddr;
	int times;

	//输入参数合法性检查
	if (argc != 3)
	{
		printf("usage: PacketLossTestClient <IPaddress> <times>");
		return -1;
	}

	//Windows Sockets Dll初始化
	frame.start_up();
	
	//创建客户端的数据报套接字,并与服务器建立连接
	ClientSocket = frame.udp_client( ( char *)argv[1], ECHOPORT, true );
	if ( ClientSocket == -1 )
		return -1;

    printf("客户端启动成功。\n");
	//开始回射请求的发送与接收
	//指明服务器的地址peer为用户输入的IP和端口号
	if (frame.set_address( ( char *)argv[1], ECHOPORT, &servaddr, "udp" ) !=0 )
		return 0;
  
	times = atoi(argv[2]);
	iResult = udp_client_fun_packetloss(times, ClientSocket );
    if(iResult == -1)
	    printf("当前测试出错!\n");
	frame.quit( ClientSocket );
    return iResult; 
}

/********************************************************
函数名:udp_client_fun_packetloss
输入参数:int times:发送次数
          SOCKET s:客户端的数据报套接字
输出参数:0:成功,-1:失败
功能:丢包率测试客户端的具体功能函数
*********************************************************/
int udp_client_fun_packetloss(int times, SOCKET s)
{
	int iResult, i =0;
    char sendline[MAXLINE];
	int recvtimes =0;
	memset(sendline,1,MAXLINE);

	//根据用户输入的发送次数循环发送相同的数据报
	printf("\r\n客户端发送%d次数据\r\n", times);
	while( i<times )
	{
		iResult = send(s,sendline,strlen(sendline),0 );
		if(iResult == SOCKET_ERROR)
		{
			printf("send 函数调用错误,错误号: %ld\n", WSAGetLastError());
			return -1;
		}
		i++;
	}		
	return iResult;
}



SocketFrame.cpp:

#include "StdAfx.h"
#include "SocketFrame.h"
#include "ws2tcpip.h"
#include "mstcpip.h"
CSocketFrame::CSocketFrame(void)
{
}

CSocketFrame::~CSocketFrame(void)
{
}
/********************************************************
函数名:set_address
输入参数:char * hname:主机名 or 点分十进制表示的IP地址
          char * sname:端口号
		  struct sockaddr_in * sap:以sockaddr_in结构存储的地址(输出参数)
          char * protocol:字符串形式描述的协议类型,如"tcp"
输出参数:0表示成功,-1表示失败。
功能:根据给定的主机名或点分十进制表示的IP地址获得以sockaddr_in结构存储的地址
*********************************************************/
int CSocketFrame::set_address(char * hname, char * sname, struct sockaddr_in * sap, char * protocol)
{
	struct servent *sp;
	struct hostent *hp;
	char *endptr;
	unsigned short port;
	unsigned long ulAddr = INADDR_NONE;


    //对地址结构socketaddr_in初始化为0,并设置地址族为AF_INET
	memset( sap,0, sizeof( *sap ) );
	sap->sin_family = AF_INET;
	
	if ( hname != NULL )
	{
		//如果hname不为空,假定给出的hname为点分十进制表示的数字地址,转换地址为sockaddr_in类型
		ulAddr = inet_addr(hname);
		if ( ulAddr == INADDR_NONE || ulAddr == INADDR_ANY) {
			//printf("inet_addr 函数调用错误,错误号: %d\n", WSAGetLastError());
			//调用错误,表明给出的是主机名,调用gethostbyname获得主机地址
			hp = gethostbyname( hname );
			if ( hp == NULL ) {
				printf("未知的主机名,错误号: %d\n", WSAGetLastError());
				return -1;
			}
			sap->sin_addr = *( struct in_addr * )hp->h_addr;
        }      
		else
			sap->sin_addr.S_un.S_addr=ulAddr;		
	}
	else
		//如果调用者没有指定一个主机名或地址,则设置地址为通配地址INADDR_ANY
		sap->sin_addr.s_addr = htonl( INADDR_ANY );
	//尝试转换sname为一个整数
	port = (unsigned short )strtol( sname, &endptr, 0 );
	if ( *endptr == '\0' )
	{
		//如果成功则转换为网络字节顺序
		sap->sin_port = htons( port );
	}
	else
	{
		//如果失败,则假定是一个服务名称,通过调用getservbyname获得端口号
		sp = getservbyname( sname, protocol );
		if ( sp == NULL ) {
			printf("未知的服务,错误号: %d\n", WSAGetLastError());
			return -1;
		}
		sap->sin_port = sp->s_port;
	}
	return 0;
}

/********************************************************
函数名:start_up
输入参数:无
输出参数:0:成功,-1:失败
功能:初始化Windows Sockets DLL,协商版本号
*********************************************************/
int CSocketFrame::start_up(void)
{
	WORD wVersionRequested;
    WSADATA wsaData;
    int iResult;

    // 使用 MAKEWORD(lowbyte, highbyte) 宏,在Windef.h 中声明
    wVersionRequested = MAKEWORD(2, 2);

    iResult = WSAStartup(wVersionRequested, &wsaData);
    if (iResult != 0) {
        //告知用户无法找到合适可用的
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值