标题:网络测试程序(完全版)
取消只看楼主
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
 问题点数:0 回复次数:7 
网络测试程序(完全版)

#include "Test.h"

struct sockaddr_in sinme;/*client socket*/
struct sockaddr_in sinhim;/*server socket*/
struct sockaddr_in frominet;
SOCKET testSocket_T, testSocket_U;/*TCP&UDP*/
SOCKET temp_tcpsocket;
SOCKET fd; /* fd of network socket */

struct hostent *addr;
extern int errno;
char *optarg;
char *Talk;

int buflen = 1024; /* length of buffer */
int delay = 0; /*milliseconds of delay before each write*/
int num = 0; /*total of packets*/
int trans = 1; /* 0 = receive, 1 = transmit mode */
int cmd = 0; /* 0 = other type, !0 = cmd*/
int performance = 0; /* */
int udp = 0; /* 0 = tcp, 1 = udp */
int ping = 0; /* 0 = other type, 1 = ping*/
int options = 0; /* socket options */
int one = 1; /* for 4.3 BSD style setsockopt() */
short port = 20001; /* port number */
char *host; /* ptr to name of host */
int optind = 1;
int offset = 0; /*0 = option+optarg , 1 = option+__optarg*/
int print = 0; /*0 = no print , 1 = print*/
int talk = 0; /*1 = talk*/
int cmdflag = 0; /* 1 = client */


char Usage[] = "\
HaoXu test v1.1\n\
Usage: test [-options] host [CLIENT]\n\
test -r [SERVER])\n\
Common options:\n\
-p# ping other host with ICMP\n\
-u use UDP instead of TCP (default TCP)\n\
-n number of packets written to network (default 1)\n\
-w milliseconds of delay before each write (default 0)\n\
-t talk to other peer\n\
format for rate:\n\
-M length ( MBytes ) of bufs read from or written to network (default 1024 Bytes)\n\
-l length ( Bytes ) of bufs read from or written to network (default 1024 Bytes)\n\
-c# command to the server\n\
format for command:\n\
-c passive send packets from the server\n\
e.g.:\n\
test -M3 X.X.X.X (send TCP 3 MBytes)\n\
test -u -l 1000 -n1000 -w500 X.X.X.X (send UDP)\n\
test -t X.X.X.X (talk to X.X.X.X)\n\
test -c passive -u -l 1000 -n1000 -w500 X.X.X.X (receive UDP from X.X.X.X)\n\
";

static BOOL UdpSend();
static BOOL UdpRecv();
static BOOL server();
static BOOL CreateTcpSock();
static BOOL CreateUdpSock();
static void mes(char* s);
static void SendTime(int byte, DWORD time);
static int getopt(int argc, char *argv[]);
static BOOL SendTcp();
static BOOL RecvTcp();
static BOOL Ping(int argc, char* argv[]);
static void fill_icmp_data(char *, int);
static USHORT checksum(USHORT *, int);
static int decode_resp(char *,int ,struct sockaddr_in *);

int main(int argc, char* argv[])
{
unsigned long addr_tmp;
int c;
WORD wVersionRequested;
WSADATA wsaData;
int error;
BOOL Bool;
char passive[] = "passive";

if (argc < 2) goto usage;

while ((c = getopt(argc, argv)) != -1)
{
switch (c)
{
case 'l':
{
buflen = atoi(optarg);
if(offset)
optind++;
break;
}

case 'u':
{
udp = 1;
break;
}

case 'n':
{
num = atoi(optarg);
if(offset)
optind++;
break;
}

case 'w':
{
delay = atoi(optarg);
if(offset)
optind++;
break;
}

case 'M':
{
buflen = atoi(optarg) * 1024 *1024;
if(offset)
optind++;
break;
}

case 'p':
{
ping = 1;
break;
}

case 'c':
{
if(strcmp(passive, optarg))
{
printf("++++++++++Command parameter error.+++++++++++++++\n");
goto usage;
}
else
{
cmd = 1;
}
if(offset)
optind++;
break;
}

case 'x':
{
performance = atoi(optarg);
if(offset)
optind++;
break;
}

case 't':
{
udp = 1;
talk = 1;
Talk = (char*)malloc(buflen-HEADLEN);
memset(Talk, 0 , buflen-HEADLEN);
break;
}

case 's':
{
print = 1;
break;
}

case 'r':
{
trans = 0;
break;
}

default:
{
goto usage;
break;
}
}
}

wVersionRequested = MAKEWORD(1, 1);

/* Initialize the WINSOCK.DLL */
error = WSAStartup(wVersionRequested, &wsaData);

/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
if(error != 0)
return 0;

/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */

if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
WSACleanup();
return 0;
}
/* The Windows Sockets DLL is acceptable. Proceed. */

memset((struct sockaddr*)&sinme, 0, sizeof(struct sockaddr));
sinme.sin_family = AF_INET;
#if defined(cray)
addr_tmp = inet_addr(INADDR_ANY);
sinme.sin_addr = addr_tmp;
#else
sinme.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
if(trans)
sinme.sin_port = 0;
else
sinme.sin_port = htons(port);

if(trans)
{
if (optind == argc)
goto usage;
memset((char *)&sinhim, 0, sizeof(sinhim));
host = argv[optind];

if (atoi(host) > 0 )
{
/* Numeric */
sinhim.sin_family = AF_INET;
#if defined(cray)
addr_tmp = inet_addr(host);
sinhim.sin_addr = addr_tmp;
#else
sinhim.sin_addr.s_addr = inet_addr(host);
#endif
}
else
{
if ((addr=gethostbyname(host)) == NULL)
mes("addr");
sinhim.sin_family = addr->h_addrtype;
CopyMemory(&addr_tmp,(const char*)addr->h_addr, sizeof(addr_tmp));
#if defined(cray)
sinhim.sin_addr = addr_tmp;
#else
sinhim.sin_addr.s_addr = addr_tmp;
#endif /* cray */
}
sinhim.sin_port = htons(port);
}


/*transmit*/
if(trans)
{
if(ping)
{
Bool = Ping(argc, argv);
if(Bool == FALSE)
{
printf("ping failed.\n");
}
}

if(udp || cmd || talk)
{
Bool = UdpSend();
if(Bool == FALSE)
{
printf("Send UDP packets failed.\n");
}
}

if(!udp && !cmd && !ping && !talk)
{
Bool = SendTcp();
if(Bool == FALSE)
{
printf("Send TCP failed.\n");
}
}
}

/*receive*/
if(!trans)
{
Bool = server();
if(Bool == FALSE)
{
printf("receive error.\n");
}
}

WSACleanup();
exit(0);

usage:
fprintf(stderr,Usage);
return (0);
}

BOOL UdpSend()
{
char* Pkt;
char* temp_ack;
pSign server_ack, pkt;
int result;
fd_set readFds;
struct timeval sockTimeout;
int i , j, maxnum, FromLen, seq;
DWORD currentTime, time;
DWORD Average = 0;
BOOL bool;

if(!cmd)
{
printf("\nUDP Transmit Test:\n");
printf(" Statistics : UDP -> %s:%d\n", inet_ntoa(sinhim.sin_addr), port);
printf(" Buffer Size = %d\n", buflen);
}

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
mes("socket");

if (bind(fd, (struct sockaddr *)&sinme, sizeof(sinme)) == INVALID_SOCKET)
mes("bind");


/* We are the client if transmitting */
if(cmd)/*if command, send format of cmd packet */
{
Pkt = (char*)malloc(HEADLEN + sizeof(Cmd));
memset(Pkt, 0, (HEADLEN + sizeof(Cmd)));
}
else/*normal format packets*/
{
Pkt = (char*)malloc(buflen);
memset(Pkt, 0, buflen);
}
pkt = (pSign)Pkt;

pkt->mType = DIAG_MSG_TYPE_REQ;
pkt->Seq = 1;
pkt->Buflen = (buflen - HEADLEN);

if(talk)
{
printf(" Send Mode : Read from STDIN\n");
pkt->cType = DIAG_CMD_TYPE_TALK;
}
else if(cmd && !talk)
{
pkt->cType = DIAG_CMD_TYPE_CMD;
((pCmd)(pkt+1))->Buflen = buflen;
((pCmd)(pkt+1))->Delay = delay;
((pCmd)(pkt+1))->Num = num;

if(udp)
{
((pCmd)(pkt+1))->Protocol = DIAG_CMD_TYPE_UDP;
}
else
{
((pCmd)(pkt+1))->Protocol = DIAG_CMD_TYPE_TCP;
}
}
else
{
pkt->cType = DIAG_CMD_TYPE_UDP;

for(j=HEADLEN,i=65;j<buflen;j++,i++)
{
if(i==91)
{
i = 48;
*(Pkt+j) = i;
}
else if(i==58)
{
i = 97;
*(Pkt+j) = i;
}
else if(i==123)
{
i = 65;
*(Pkt+j) = i;
}
else
*(Pkt+j) = i;
}
}

seq = 0;

if( num == 0 || talk || cmd )/* talk or cmd */
{
maxnum = 1;
}
else if( !talk && !cmd )/*send UDP packets*/
{
maxnum = num;
}

for(i=0; i<maxnum ;i++)
{
pkt->Time = GetTickCount();
pkt->Sendnum = maxnum;

if(talk)
{
while(1)
{
scanf("%s", Talk);
memcpy(((char*)pkt+HEADLEN), Talk, buflen - HEADLEN);
if(sendto(fd, (char*)pkt, buflen, 0, (struct sockaddr*)&sinhim, sizeof(struct sockaddr)) == INVALID_SOCKET)
{
mes("send");
}
}
}

if(sendto(fd, (char*)pkt, cmd?(HEADLEN + sizeof(Cmd)):buflen, 0, (struct sockaddr*)&sinhim, sizeof(struct sockaddr)) == INVALID_SOCKET)
{
mes("send");
}

if(cmd)
{
cmdflag = 1;
sinme.sin_port = htons(port);
free(Pkt);
bool = server();
if(bool == FALSE)
return (FALSE);
}

if(!talk && !cmd)
{
sockTimeout.tv_sec = TIMEOUT;
sockTimeout.tv_usec = 0;

/* Wait for reply at the ephemeral port selected by the sendto () call. */
FD_ZERO (&readFds);
FD_SET (fd, &readFds);

result = select (0, &readFds, NULL, NULL, &sockTimeout);

if (result < 0)
{
return (FALSE);
}

if (result == 0) /* TIMEOUT interval expired. */
{
printf("Request timed out.\n");
}

FromLen = sizeof(sinhim);
temp_ack = malloc(HEADLEN);
if(result > 0)
{
result = recvfrom(fd, (char*)temp_ack, HEADLEN, 0, (struct sockaddr*)&sinhim, &FromLen);
if(result == INVALID_SOCKET)
{
mes("recvfrom");
}

server_ack = (pSign)temp_ack;
currentTime = GetTickCount();

if((server_ack->cType == DIAG_CMD_TYPE_UDP) && (server_ack->mType == DIAG_MSG_TYPE_ACK))
{
time = currentTime - server_ack->Time;
seq += 1;
}
pkt->Seq += 1;
Average += time;

free(temp_ack);
Sleep(delay);
}
}
}

free(Pkt);
SendTime(buflen*seq, Average);
if(!talk && !cmd)
{
printf("+++ %d bytes in %2.2f real seconds = %2.2f KB/sec +++\n", buflen*seq, (float)Average/CLOCKS_PER_SEC, (float)Average/CLOCKS_PER_SEC == 0?0:((float)(buflen*seq)/(float)(Average*1024))*CLOCKS_PER_SEC);
}

return (TRUE);
}

BOOL UdpRecv()
{
int rlt = 0;
int FromLen;
Sign udp_ack;
char *TALK;
short cli_port;
char* cli_addr;
pSign client_req;
char temp_req[TEMPBUF];

FromLen = sizeof(sinhim);
rlt = recvfrom(testSocket_U, (char*)&temp_req, TEMPBUF, 0, (struct sockaddr*)&sinhim, &FromLen);

if (rlt < 0)
{
printf("Receive UDP packets failed.\n");
return (FALSE);
}

client_req = (pSign)temp_req;

if((client_req->cType == DIAG_CMD_TYPE_TALK) && (client_req->mType == DIAG_MSG_TYPE_REQ))
{
TALK = (char*)malloc(buflen);
memset(TALK, 0, buflen);
memcpy(TALK, (client_req+1), buflen-HEADLEN);
cli_port = (short)ntohs(sinhim.sin_port);
cli_addr = inet_ntoa(sinhim.sin_addr);
printf("Writing Received Data from %s:%d: ", cli_addr, cli_port);
printf("\t%s\n", TALK);
}

if((client_req->cType == DIAG_CMD_TYPE_CMD) && (client_req->mType == DIAG_MSG_TYPE_REQ))
{
Sleep(200);
sinme.sin_port = 0;
sinhim.sin_port = htons(port);
buflen = ((pCmd)(client_req+1))->Buflen;
delay = ((pCmd)(client_req+1))->Delay;
num = ((pCmd)(client_req+1))->Num;

if(((pCmd)(client_req+1))->Protocol == DIAG_CMD_TYPE_UDP)
{
udp = 1;
UdpSend();
}
else if(((pCmd)(client_req+1))->Protocol == DIAG_CMD_TYPE_TCP)
{
udp = 0;
SendTcp();
}
sinme.sin_port = htons(port);
}

if((client_req->cType == DIAG_CMD_TYPE_TIME) && (client_req->mType == DIAG_MSG_TYPE_REQ))
{
printf(" in %2.2f real seconds = %2.2f KB/sec +++\n", (float)client_req->Time/CLOCKS_PER_SEC, (float)client_req->Time/CLOCKS_PER_SEC == 0?0:((float)client_req->Totalbuflen/(float)(client_req->Time*1024))*CLOCKS_PER_SEC);
if(cmdflag)
{
exit (0);
}
}

if((client_req->cType == DIAG_CMD_TYPE_UDP) && (client_req->mType == DIAG_MSG_TYPE_REQ))
{
memset(&udp_ack, 0 , HEADLEN);
udp_ack.cType = DIAG_CMD_TYPE_UDP;
udp_ack.mType = DIAG_MSG_TYPE_ACK;
udp_ack.Seq = client_req->Seq;
udp_ack.Time = client_req->Time;
udp_ack.Buflen= 0;
if(udp == 0 )
{
udp = 1;
}
else
udp += 1;

if(sendto(testSocket_U, (char*)&udp_ack, HEADLEN, 0, (struct sockaddr*)&sinhim, sizeof(struct sockaddr)) == INVALID_SOCKET)
{
printf("Reply failed.\n");
return (FALSE);
}

if(client_req->Seq == client_req->Sendnum)
{
cli_port = (short)ntohs(sinhim.sin_port);
cli_addr = inet_ntoa(sinhim.sin_addr);
printf("+++ Received UDP %d Bytes from %s:%d", cmd==1?(client_req->Buflen+HEADLEN)*(udp-1):(client_req->Buflen+HEADLEN)*udp, cli_addr, cli_port);
udp = 0;
}
}
return (TRUE);
}


BOOL SendTcp()
{
int i, j, k,result, templen, tcpbuf;
char *temp_send, *temp_recv, *temp_tcp;
pSign req_tcp;
struct timeval sockTimeout;
DWORD currentTime, time;
fd_set readFds;
BOOL SockOpt;

printf("\nTCP Transmit Test:\n");
printf(" Transmit : TCP -> %s:%d\n", inet_ntoa(sinhim.sin_addr), port);
printf(" Buffer Size : %d\n", buflen);


temp_send = malloc(buflen);
memset((char *)temp_send, 0, buflen);
req_tcp = (pSign)temp_send;
req_tcp->Seq = 1;

for(k=0;num==0?k<1:k<num;k++)
{
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
mes("socket");

SockOpt = TRUE;
result = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&SockOpt, sizeof(SockOpt));

if (bind(fd, (struct sockaddr *)&sinme, sizeof(sinme)) == SOCKET_ERROR)
mes("bind");

if(connect(fd, (struct sockaddr*)&sinhim, sizeof(sinhim)) == SOCKET_ERROR)
mes("connect");

req_tcp->cType = DIAG_CMD_TYPE_TCP;
req_tcp->mType = DIAG_MSG_TYPE_REQ;
req_tcp->Buflen = (buflen - HEADLEN);
num==0?(req_tcp->Sendnum=1):(req_tcp->Sendnum=num);
if(num == 0)
req_tcp->Sendnum = 1;
else
req_tcp->Sendnum = num;


for(j=HEADLEN,i=65;j<buflen;j++,i++)
{
if(i==91)
{
i = 48;
*(temp_send+j) = i;
}
else if(i==58)
{
i = 97;
*(temp_send+j) = i;
}
else if(i==123)
{
i = 65;
*(temp_send+j) = i;
}
else
*(temp_send+j) = i;
}

req_tcp->Time = GetTickCount();

if(send(fd, (char *)req_tcp, buflen, 0) == INVALID_SOCKET)
mes("send");

temp_recv = (char*)malloc(HEADLEN);
temp_tcp = (char*)malloc(HEADLEN);
memset((char *)temp_recv, 0, HEADLEN);
memset((char *)temp_tcp, 0, HEADLEN);

sockTimeout.tv_sec = TIMEOUT*4;
sockTimeout.tv_usec = 0;

/* Wait for reply at the ephemeral port selected by the sendto () call. */
FD_ZERO (&readFds);
FD_SET (fd, &readFds);

result = select (0, &readFds, NULL, NULL, &sockTimeout);

if (result < 0)
{
printf("TCP select failed.\n");
free(temp_recv);
free(temp_tcp);
free(temp_send);
return (FALSE);
}

if (result == 0) /* TIMEOUT interval expired. */
{
printf("Request time out.\n");
free(temp_recv);
free(temp_tcp);
free(temp_send);
return (FALSE);
}

if (result > 0)
{
if(req_tcp->cType == DIAG_CMD_TYPE_TCP && req_tcp->mType == DIAG_MSG_TYPE_REQ && req_tcp->Cmd[0] == 0)
{
templen = 0;
tcpbuf = HEADLEN;

while(1)
{
result = recv(fd, (char*)temp_recv, tcpbuf, 0);
if(result == -1)
{
mes("recv");
}

if(result> 0 && result < tcpbuf)
{
tcpbuf -= result;
memcpy((char *)(temp_tcp + templen), temp_recv, result);
templen += result;
}
else if(result > 0 && result == tcpbuf)
{
memcpy((temp_tcp + templen), temp_recv, result);
break;
}
}
}


if(((pSign)temp_tcp)->cType == DIAG_CMD_TYPE_TCP && ((pSign)temp_tcp)->mType == DIAG_MSG_TYPE_ACK)
{
currentTime = GetTickCount();
time = currentTime - ((pSign)temp_tcp)->Time;
req_tcp->Seq += 1;
}

}
SendTime(buflen, time);
printf("+++ %d bytes in %2.2f real seconds = %2.2f KB/sec +++\n", buflen, (float)time/CLOCKS_PER_SEC, (float)time/CLOCKS_PER_SEC == 0?0:((float)(buflen)/(float)(time*1024))*CLOCKS_PER_SEC);
Sleep(delay);
free(temp_recv);
free(temp_tcp);
shutdown(fd, SD_BOTH);
closesocket(fd);
}

free(temp_send);
return (TRUE);
}


搜索更多相关主题的帖子: 网络 SOCKET struct socket 
2007-01-10 13:43
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

[CODE]BOOL RecvTcp()
{
int tcpbuf, rlt, templen, fromlen, seq;
char signflag;/*0 = receive sign , 1 = receive buf */
char *temp_tcp, *temp_sign;
pSign client_req;
Sign Reply;
short cli_port;
char* cli_addr;
fromlen = sizeof(frominet);
if((testSocket_T = accept(temp_tcpsocket, (struct sockaddr*)&frominet, &fromlen)) == INVALID_SOCKET)
{
printf("accept failed.\n");
return (FALSE);
}

signflag = 0;
templen = 0;
tcpbuf = HEADLEN;
temp_sign = malloc(HEADLEN);
temp_tcp = malloc(HEADLEN);
memset((char *)temp_sign, 0, HEADLEN);
memset((char *)temp_tcp, 0, HEADLEN);
recvtcp:
while(1)
{
rlt = recv(testSocket_T, (char*)temp_tcp, tcpbuf, 0);
if(rlt == -1)
mes("recv");
if(rlt > 0 && rlt < tcpbuf)
{
if(signflag == 0)
{
tcpbuf -= rlt;
memcpy((char *)(temp_sign + templen), temp_tcp, rlt);
templen += rlt;
}
else
{
tcpbuf -= rlt;
}
}
else if(rlt > 0 && rlt == tcpbuf)
{
if(signflag == 0)
{
memcpy((char *)(temp_sign + templen), temp_tcp, rlt);
client_req = (pSign)temp_sign;
tcpbuf = client_req->Buflen;
signflag = 1;
free(temp_tcp);
temp_tcp = (char*)malloc(tcpbuf);
memset(temp_tcp, 0, tcpbuf);
}
else
{
break;
}
}
}

if((client_req->cType == DIAG_CMD_TYPE_TCP) && (client_req->mType == DIAG_MSG_TYPE_REQ) && (client_req->Cmd[0] == 0))
{
Reply.cType = DIAG_CMD_TYPE_TCP;
Reply.mType = DIAG_MSG_TYPE_ACK;
Reply.Seq = client_req->Seq;
Reply.Time = client_req->Time;
signflag = 0;
templen = 0;
tcpbuf = HEADLEN;
seq = client_req->Seq;
rlt = send(testSocket_T, (const char*)&Reply, sizeof(Reply), 0);
if(rlt == -1)
{
printf("TCP reply failed.\n");
return (FALSE);
}
cli_port = (short)ntohs(frominet.sin_port);
cli_addr = inet_ntoa(frominet.sin_addr);
printf("+++ Received TCP %d Bytes from %s:%d", client_req->Buflen+HEADLEN, cli_addr, cli_port);
goto recvtcp;
}
if((client_req->cType == DIAG_CMD_TYPE_TIME) && (client_req->mType == DIAG_MSG_TYPE_REQ))
{
printf(" in %2.2f real seconds = %2.2f KB/sec +++\n", (float)client_req->Time/CLOCKS_PER_SEC, (float)client_req->Time/CLOCKS_PER_SEC == 0?0:((float)client_req->Totalbuflen/(float)(client_req->Time*1024))*CLOCKS_PER_SEC);
}
if(cmdflag && client_req->Sendnum == seq)
{
shutdown(testSocket_T, SD_BOTH);
closesocket(testSocket_T);
free(temp_tcp);
free(temp_sign);
exit (0);
}
/*
if(!cmdflag && client_req->Sendnum == client_req->Seq)
seq = 0;
*/
shutdown(testSocket_T, SD_BOTH);
closesocket(testSocket_T);
free(temp_tcp);
free(temp_sign);
return (TRUE);
}
BOOL server()
{
int rlt = 0;
struct hostent* SerInfo;
fd_set readFds;
BOOL bool;
if(cmd)
SerInfo = gethostbyaddr((char*)&sinme.sin_addr.s_addr , 4, PF_INET);
else
SerInfo = gethostbyaddr((char*)&sinhim.sin_addr.s_addr , 4, PF_INET);
printf("Receive Test\n Local Host : %s\n", SerInfo->h_name);
printf("************\n Listening...: On port %d\n", port);

bool = CreateTcpSock();
if(bool == FALSE)
{
printf("Create tcpsocket failed.\n");
return (FALSE);
}
bool = CreateUdpSock();
if(bool == FALSE)
{
printf("Create udpsocket failed.\n");
return (FALSE);
}
for(;;)
{
FD_ZERO (&readFds);
FD_SET (temp_tcpsocket, &readFds);
FD_SET (testSocket_U, &readFds);
rlt = select (0, &readFds, NULL, NULL, NULL);
if(rlt < 0)
{
printf("select error.\n");
return (FALSE);
}
if(FD_ISSET(temp_tcpsocket, &readFds))
{
bool = RecvTcp();
if(bool == FALSE)
{
printf("TCP receive failed.\n");
return (FALSE);
}
}
else if(FD_ISSET(testSocket_U, &readFds))
{
bool = UdpRecv();
if(bool == FALSE)
{
printf("UDP receive failed.\n");
return (FALSE);
}
}
else
{
printf("Receive error packets.\n");
return (FALSE);
}
}
}
BOOL CreateTcpSock()
{
static int result;
BOOL SockOpt;
temp_tcpsocket = socket(AF_INET,SOCK_STREAM,0);
if(temp_tcpsocket < 0)
{
mes("socket");
}
SockOpt = TRUE;
setsockopt(temp_tcpsocket, SOL_SOCKET, SO_REUSEADDR, (char*)&SockOpt, sizeof(SockOpt));
if((bind(temp_tcpsocket,(struct sockaddr*)&sinme,sizeof(sinme))) == INVALID_SOCKET)
{
mes("TCP bind");
}
if(listen(temp_tcpsocket, 5) == INVALID_SOCKET)
{
printf("the socket is invalid or unable to listen.\n");
return (FALSE);
}

return (TRUE);
}

BOOL CreateUdpSock()
{
static int result;
testSocket_U = socket(AF_INET,SOCK_DGRAM,0);
if(testSocket_U == INVALID_SOCKET)
{
mes("socket");
}
if((bind(testSocket_U,(struct sockaddr*)&sinme,sizeof(sinme))) != 0)
{
mes("UDP bind");
}
return (TRUE);
}

void mes(char *s)
{
printf("*** Winsock Error: %s: %s Failed; Error: %d ***\n\n\n\n", trans?"-t":"-r", s, WSAGetLastError());
if(trans)
{
closesocket(fd);
}
else if(!trans)
{
closesocket(testSocket_T);
closesocket(testSocket_U);
}
WSACleanup();
exit(1);
}
void SendTime(int byte, DWORD time)
{
char* Pkt;
pSign pkt;
Pkt = (char*)malloc(HEADLEN);
pkt = (pSign)Pkt;
pkt->cType = DIAG_CMD_TYPE_TIME;
pkt->mType = DIAG_MSG_TYPE_REQ;
pkt->Time = time;
pkt->Totalbuflen = byte;
pkt->Buflen = 1000;
if(num == 0)
pkt->Sendnum = 1;
else
pkt->Sendnum = num;
if(udp)
{
if(sendto(fd, (char*)pkt, HEADLEN, 0, (struct sockaddr*)&sinhim, sizeof(struct sockaddr)) == INVALID_SOCKET)
{
mes("send");
}
}
else
{
if(send(fd, (char *)pkt, 1024, 0) == INVALID_SOCKET)
mes("send");
}
free(Pkt);
}
int getopt(int argc, char *argv[])
{
int option;
char *p;
if (optind == argc)
return -1;
p = argv[optind];
if (*p != '-')
return -1;
option = *(++p);
p++;
offset = 0;
if (*p != '\0')
{
offset = 0;
optarg = p;
}
else
{
offset = 1;
optarg = argv[optind + 1];
}
/* increment count for next function call */
optind++;
return option;
}

BOOL Ping(int argc, char* argv[])
{
SOCKET sockRaw;
struct sockaddr_in dest,from;
struct hostent * hp;
int bread,datasize,times, i, bwrote, currentTime;
int fromlen = sizeof(from);
int timeout = 1000;
int statistic = 0; /* total of packets */
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no = 0;
int Average = 0;
int Minimum = 0;
int Maximum = 0;
sockRaw = WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL, 0,WSA_FLAG_OVERLAPPED);
if (sockRaw == INVALID_SOCKET)
{
fprintf(stderr,"WSASocket() failed: %d\n",WSAGetLastError());
return (FALSE);
}
bread = setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());
return (FALSE);
}
timeout=1000 ;
bread = setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());
return (FALSE);
}
memset(&dest, 0, sizeof(dest));
hp = gethostbyname(argv[optind]);
if (!hp)
{
addr = inet_addr(argv[optind]);
}
if ((!hp) && (addr == INADDR_NONE) )
{
fprintf(stderr,"Unable to resolve %s\n",argv[optind]);
return (FALSE);
}
if (hp != NULL)
memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
else
dest.sin_addr.s_addr = addr;
if (hp)
dest.sin_family = hp->h_addrtype;
else
dest.sin_family = AF_INET;
dest_ip = inet_ntoa(dest.sin_addr);
if(num == 0)
{
times = 4;
}
else
{
times = num;
}
datasize =buflen + ICMP_MIN;
icmp_data = (char*)malloc(datasize);
recvbuf = (char*)malloc(datasize);
if (!icmp_data)
{
fprintf(stderr,"HeapAlloc failed %d\n",GetLastError());
return (FALSE);
}
memset(icmp_data, 0, datasize);
fill_icmp_data(icmp_data,datasize);
fprintf(stdout,"\nPinging %s ....\n\n",dest_ip);
for(i=0; i < times; i++)
{
((IcmpHeader*)icmp_data)->i_cksum = 0;
((IcmpHeader*)icmp_data)->i_seq = seq_no++;
((IcmpHeader*)icmp_data)->timestamp = GetTickCount();
((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data,datasize);
if((bwrote = sendto(sockRaw, icmp_data, datasize, 0, (struct sockaddr*)&dest, sizeof(dest))) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf("Request timed out.\n");
continue;
}
}
if (bwrote < datasize )
{
fprintf(stdout,"Wrote %d bytes\n",bwrote);
}
bread = recvfrom(sockRaw,recvbuf,TEMPBUF, 0, (struct sockaddr*)&from, &fromlen);
if(bread == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
printf("Request timed out.\n");
continue;
}
}
currentTime = decode_resp(recvbuf, bread, &from);
if(currentTime != -1)
statistic++;
if(i==0)
{
Maximum = currentTime;
Minimum = currentTime;
}
else
{
if(Maximum<currentTime)
{
Maximum = currentTime;
}
if(Minimum>currentTime)
{
Minimum = currentTime;
}
}
Average += currentTime;
if(delay == 0)
Sleep(200);
else
Sleep(delay);
}
/*
Display the statistic result
*/
fprintf(stdout,"\nPing statistics for %s \n",dest_ip);
fprintf(stdout," Packets: Sent = %d,Received = %d, Lost = %d (%2.0f%% loss)\n",times,
statistic,(times-statistic),(float)(times-statistic)/times*100);
printf("Approximate round trip times in milli-seconds:\n");
printf(" Minimum = %dms, Maximum = %dms, Average = %2.0fms\n\n", Minimum, Maximum, (float)Average/(float)statistic);
return (TRUE);
}

/*
The response is an IP packet. We must decode the IP header to locate
the ICMP data
*/
int decode_resp(char *buf, int bytes,struct sockaddr_in *from)
{
IpHeader *iphdr;
IcmpHeader *icmphdr;
unsigned short iphdrlen;
iphdr = (IpHeader *)buf;
iphdrlen = (iphdr->h_len) * 4 ; // number of 32-bit words *4 = bytes
if (bytes < iphdrlen + ICMP_MIN)
{
printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));
}
icmphdr = (IcmpHeader*)(buf + iphdrlen);
if (icmphdr->i_type != ICMP_ECHOREPLY)
{
fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type);
return -1;
}
if (icmphdr->i_id != (USHORT)GetCurrentProcessId())
{
fprintf(stderr,"someone else's packet!\n");
return -1;
}
printf("%d bytes from %s:",bytes, inet_ntoa(from->sin_addr));
printf(" icmp_seq = %d. ",icmphdr->i_seq+1);
printf(" time: %d ms\n",GetTickCount()-icmphdr->timestamp);
return (GetTickCount()-icmphdr->timestamp);
}

USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
/*
Helper function to fill in various stuff in our ICMP request.
*/
void fill_icmp_data(char * icmp_data, int datasize)
{
int i, j;
IcmpHeader *icmp_hdr;
icmp_hdr = (IcmpHeader*)icmp_data;
icmp_hdr->i_type = ICMP_ECHO;
icmp_hdr->i_code = 0;
icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
icmp_hdr->i_cksum = 0;
icmp_hdr->i_seq = 0;
/* Place some junk in the buffer.*/
for(j = sizeof(IcmpHeader),i=65; j<(buflen + ICMP_MIN); j++,i++)
{
if(i==91)
{
i = 48;
*(icmp_data+j) = i;
}
else if(i==58)
{
i = 97;
*(icmp_data+j) = i;
}
else if(i==123)
{
i = 65;
*(icmp_data+j) = i;
}
else
*(icmp_data+j) = i;
}
}[/CODE]


2007-01-10 13:44
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

上面两个放到test.c里 下面这个是头文件 放到test.h中
[CODE]
#pragma pack(4)
#include <stdio.h>
#include <io.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define TEMPBUF 8*1024
#define HEADLEN 24
#define TIMEOUT 5
#define NOPAD 4
#define DEBUG 0
#define TRUE 1
#define FALSE 0
#define LOCALTEST 1
typedef int BOOL;
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
#define DIAG_CMD_TYPE_TALK 1
#define DIAG_CMD_TYPE_PERF 2
#define DIAG_CMD_TYPE_CMD 3
#define DIAG_CMD_TYPE_TCP 4
#define DIAG_CMD_TYPE_UDP 5
#define DIAG_CMD_TYPE_TIME 6
#define DIAG_MSG_TYPE_REQ 0
#define DIAG_MSG_TYPE_ACK 1

/* The IP header */
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum
unsigned int sourceIP;
unsigned int destIP;
}IpHeader;

/* ICMP header*/
typedef struct icmphdr {
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
}IcmpHeader;
/*TEST header*/
typedef struct _sign
{
char cType;/*command type*/
char mType;/*message type*/
short Sendnum;
int Seq;
clock_t Time;
char Cmd[4];
int Totalbuflen;
int Buflen;
}Sign, *pSign;
typedef struct _cmd
{
int Buflen;
int Delay;
int Num;
char Protocol;
char buf[3];
}Cmd, *pCmd;[/CODE]


2007-01-10 13:46
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

使用VC编译 连接时需加入ws2_32.lib
下面给出一个编译好的例子
需要学习网络编程的朋友可以看看
里面包括的TCP,UDP,ICMP的传输以及多种功能的应用 例如测量上行,下行带宽,简单聊天等功能
具体用法可以参照打印出来的例子
Usage: test [-options] host [CLIENT]\n\
test -r [SERVER])\n\
Common options:\n\
-p# ping other host with ICMP\n\
-u use UDP instead of TCP (default TCP)\n\
-n number of packets written to network (default 1)\n\
-w milliseconds of delay before each write (default 0)\n\
-t talk to other peer\n\
format for rate:\n\
-M length ( MBytes ) of bufs read from or written to network (default 1024 Bytes)\n\
-l length ( Bytes ) of bufs read from or written to network (default 1024 Bytes)\n\
-c# command to the server\n\
format for command:\n\
-c passive send packets from the server\n\
e.g.:\n\
test -M3 X.X.X.X (send TCP 3 MBytes)\n\
test -u -l 1000 -n1000 -w500 X.X.X.X (send UDP)\n\
test -t X.X.X.X (talk to X.X.X.X)\n\
test -c passive -u -l 1000 -n1000 -w500 X.X.X.X (receive UDP from X.X.X.X)\n\

下面是编译过的exe文件

oCAYEGPV.rar (44.09 KB)

[此贴子已经被作者于2007-1-10 13:53:27编辑过]


2007-01-10 13:51
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 
那是因为没有加ws2_32.lib
alt+f7在连接那一块加(VC)

2007-01-10 14:07
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

使用方法看USAGE就好 再不知道可以说明一下
我会跟帖解答滴


2007-01-10 14:34
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

ICMP的代码拿别人的加了点功能 其他的都自己写的
其实这种网络编程的流程几乎是这样的 中间根据自己写的东西加一些功能就可以了
其他有很多函数可以使用的


2007-01-10 16:25
hao0716
Rank: 4
等 级:业余侠客
威 望:1
帖 子:353
专家分:222
注 册:2006-4-11
得分:0 

发送网络包 用TCP或者UDP 可以测量网络环境的
比如发送10M的数据测量带宽等
比如说一般人知道的ping功能本程序就可以实现

聊天也可以 比如你编译好的程序叫test
你放到c盘下面 然后打开MSDOS 到C:\下输入test -r 就代表服务器
再开一个MSDOS 输入test -t 127.0.0.1就可以和自己通话了
这个127.0.0.1代表你自己的IP 当然你也可以到另一台电脑上开test -r
然后发送数据 这个通话功能是利用UDP完成的一个小功能
顺便一说 这个程序是基于C/S模式下的 必须要开服务器
ping 功能除外
ping功能的使用方法:test -p www.sohu.com 这个是ping SOHU的


2007-01-10 16:48



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-115259-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.647758 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved