超级简单的UDP通信例子,能通信几个UDP包,就接收不到数据了,请帮忙看看?

fujoey 2012-07-13 02:16:55
做了一个UDP的例子,用来测试PC机和单板通信,UDP的性能。为了对照,也做了PC机的版本。程序分两部分,一个是服务器,收到UDP包,直接发送回去。另外一个是客户端,向服务器发送UDP包,再接收;一直如此循环。
一样的流程,在PC机和单板之间工作正常。但是在PC机上,却工作不正常。客户端发送UDP包后,一直收不到包。想不通原因。
如果是客户端有问题,单板和PC机却能一直通信。如果是服务器段有问题,终止客户端后,再启动客户端,又可以在客户端和服务器短之间发送一些UDP数据。调试客户端,挂在recvfrom上。
下面贴出服务器和客户端的例子,使用visual studio 2010 express版本编译的。
想用wireshark 1.8抓包。UDP通信,只抓到一个方向的包。没有看到另外一个方向的包。很奇怪。应该有两个方向的数据,否则单板通信会停止的。wireshark是不是哪儿有什么显示的过滤设置?


server 代码
============================

// userver.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>


//#include <winsock.h>
#include <winsock2.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <windows.h>


#pragma comment(lib, "Ws2_32.lib")

#define UDP_TSET_DATA_BYTES 20000000
#define BUFF_MAX_LEN 8000
#define SERV_PORT_NUM 8888



int udp_echo_server( void )
{
int iStatus;
int iLen,iLenSent;
int sockfd;
socklen_t i_client_addr_len;
struct sockaddr_in server_addr, client_addr;


char mesg[BUFF_MAX_LEN];

sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */

/* init server_addr */
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERV_PORT_NUM);

/* bind address and port to socket */
iStatus = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if( 0 != iStatus )
{
printf("bind error:%d", iStatus);
exit(1);
}

i_client_addr_len = sizeof(client_addr);
for( ; ; )
{
//printf("+");
/* waiting for receive data */
iLen = recvfrom(sockfd, mesg, BUFF_MAX_LEN, 0, (struct sockaddr *)&client_addr, &i_client_addr_len);
if( iLen<0 )
{
printf("recvfrom error:%d from:%s", iLen, inet_ntoa(client_addr.sin_addr));
printf("Winsock error:%d\n", WSAGetLastError());
exit(1);
}

/* sent data back to client */
//printf("-");
iLenSent=sendto(sockfd, mesg, iLen, 0, (struct sockaddr *)&client_addr, i_client_addr_len);
if( iLenSent!=iLen )
{
printf("sendto error:Only sent %d of %d to %s", iLenSent, iLen, inet_ntoa(client_addr.sin_addr));
printf("Winsock error:%d\n", WSAGetLastError());
exit(1);
}
}

return 0;
}


int main( void )
{

WORD wVersionRequested;
WSADATA wsaData;
int err;

/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}

udp_echo_server( );

WSACleanup();

return 0;
}


client 代码
==========================================
// udp_client.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>


//#include <winsock.h>
#include <winsock2.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <windows.h>


#pragma comment(lib, "Ws2_32.lib")

#define UDP_TSET_DATA_BYTES 20000000
#define BUFF_MAX_LEN 8000
#define SERV_PORT_NUM 8888


int udp_client
(
int iServAddr,
int iPacketSize,
int iPrePacketNum,
int iDataNum,
int iReportDataNum
)
{

int i;
int iStatus;
int iPacketNum;
int iTransmitLen;
char sendline[BUFF_MAX_LEN], recvline[BUFF_MAX_LEN + 1];

int iReportPacketNum;

int sockfd;
int begin_second, end_second;

struct sockaddr_in servaddr;
struct sockaddr_in fromaddr;
int fromlen;



/* init server address */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_addr.S_un.S_addr=iServAddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT_NUM);

/* check args */
printf("\nServer IP:%s.", inet_ntoa(servaddr.sin_addr));
printf("\nPacket size:%d bytes.", iPacketSize);
printf("\nPacket number sent out before loop:%d.", iPrePacketNum);
printf("\nData :%d bytes.", iDataNum);
printf("\nReport every data :%d bytes.\n", iReportDataNum);
iReportPacketNum = iReportDataNum/iPacketSize;

// Initialize buffer
for( i=0; i<iPacketSize; i++)
{
sendline[i] = 0x30+i;
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if( NULL== sockfd)
{
printf("socket error");
return -1;
}

#if 1
/* connect to server */
iStatus= connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if( iStatus < 0 )
{
printf("connect error:%d", iStatus);
return -1;
}
#endif

iPacketNum = (iDataNum/iPacketSize);
begin_second = time((time_t*)NULL);

// Send out some packets in order to reduce the affect of latency
for( i=0; i<iPrePacketNum; i++)
{
/* send a line to server */
//write(sockfd, sendline, iPacketSize);
iTransmitLen = send(sockfd, sendline, iPacketSize, 0);
//iTransmitLen = sendto(sockfd, sendline, iPacketSize, 0, (LPSOCKADDR)&servaddr, sizeof(servaddr));
if( iTransmitLen != iPacketSize )
{
printf("sendto error:%d for pre-packets\n", iTransmitLen);
printf("Winsock error:%d\n", WSAGetLastError());
printf("Server IP:%s.\n", inet_ntoa(servaddr.sin_addr));
return -1;
}
}

for( i=0; i<iPacketNum; i++)
{
/* send a line to server */
//write(sockfd, sendline, iPacketSize);
iTransmitLen = send(sockfd, sendline, iPacketSize, 0);
//iTransmitLen = sendto(sockfd, sendline, iPacketSize, 0, (LPSOCKADDR)&servaddr, sizeof(servaddr));
if( iTransmitLen != iPacketSize )
{
printf("sendto error:%d for loop-packets\n", iTransmitLen);
printf("Winsock error:%d\n", WSAGetLastError());
printf("Server IP:%s.\n", inet_ntoa(servaddr.sin_addr));
return -1;
}

/* receive data from server */
fromlen=sizeof(fromaddr);
//iTransmitLen = read(sockfd, recvline, iPacketSize);
iTransmitLen = recv(sockfd, recvline, iPacketSize, 0);
//iTransmitLen=recvfrom(sockfd, recvline, iPacketSize,0,(LPSOCKADDR)&fromaddr,&fromlen);
if( iTransmitLen < 0 )
{
printf("read error:%d for loop-packets\n", iTransmitLen);
printf("Winsock error:%d\n", WSAGetLastError());
printf("Server IP:%s.\n", inet_ntoa(servaddr.sin_addr));
return -1;
}

if( (iReportPacketNum-1) == (i%iReportPacketNum) )
{
printf("+");
}

// verify if necessary
}

#if 0
printf("\n::...\n");
for( i=0; i<iPrePacketNum; i++)
{

/* receive data from server */
iTransmitLen = recv(sockfd, recvline, iPacketSize, 0);
fromlen=sizeof(fromaddr);
//iTransmitLen=recvfrom(sockfd, recvline, iPacketSize,0,(LPSOCKADDR)&fromaddr,&fromlen);
if( iTransmitLen < 0 )
{
printf("read error:%d for post-packets at %d(%d) post-packets", iTransmitLen, i, iPrePacketNum);
return -1;
}
}
#endif

end_second = time((time_t*)NULL);
printf("UDP sent %d bytes in %d seconds\n", iDataNum, end_second-begin_second);
printf("UDP speed:%d KBps for %d bytes packet\n", (iPacketNum*iPacketSize/1000)/(end_second-begin_second), iPacketSize);
printf("UDP speed:%d Kpps for %d bytes packet\n", (iPacketNum/1000)/(end_second-begin_second), iPacketSize);

return 0;
}


int main(int argc, char **argv)
{

int i;
int iPacketSize;
int iPrePacketNum;
int iDataNum;
int iReportDataNum;
int iAutoLoop;

int iServAddr;
int iServerAddrStatus;

char *endptr;

WORD wVersionRequested;
WSADATA wsaData;
int err;

/* check args */
if( argc <6 )
{
printf("\nUsage:");
printf("\n%s server_IP_address packet_size packet_num_before data_size data_num_report auto_loop\n", argv[0]);
}


printf("\n%s ", argv[0]);
if( argc > 1 )
{
printf("%s ", argv[1]);
//iServAddr=inet_addr(argv[1]);
iServerAddrStatus=inet_pton(AF_INET, argv[1], &iServAddr);
if( iServerAddrStatus <= 0 )
{
printf("[%s] is not a valid IPaddress\n", argv[1]);
return -1;
}
}
else
{
//inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
iServAddr=inet_addr("127.0.0.1");
//iServAddr=inet_addr("192.168.1.10");
}

if( argc > 2 )
{
printf("%s ", argv[2]);
iPacketSize = strtol(argv[2], &endptr, 10);
}
else
{
iPacketSize = 38;
}

if( argc > 3 )
{
printf("%s ", argv[3]);
iPrePacketNum = strtol(argv[3], &endptr, 10);
}
else
{
iPrePacketNum = 2000/iPacketSize;
}

if( argc > 4 )
{
printf("%s ", argv[4]);
iDataNum = strtol(argv[4], &endptr, 10);
}
else
{
iDataNum = UDP_TSET_DATA_BYTES;
}

if( argc > 5 )
{
printf("%s ", argv[5]);
iReportDataNum = strtol(argv[5], &endptr, 10);
}
else
{
iReportDataNum = UDP_TSET_DATA_BYTES/50;
}

if( argc > 6 )
{
printf("%s ", argv[6]);
if( 0 == strcmp(argv[6], "auto_loop") )
{
iAutoLoop = 1;
printf("\nGo through packet size automatically.\n");
}
}
else
{
iAutoLoop = 0;
}

/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
{
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}

for( i=iPacketSize; i<2000; i+=100 )
{
udp_client( iServAddr, i, iPrePacketNum, iDataNum, iReportDataNum );
if ( 1!= iAutoLoop )
{
break;
}
}

WSACleanup();

return 0;
}



...全文
112 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧