【发布时间】:2013-12-02 14:00:58
【问题描述】:
我想从服务器应用程序(在同一台计算机上)接收 UDP 数据包,并将其转发到不同端口上的 UDP 接收应用程序。 服务器应用不是我的,我也没有源代码。
UDP 接收应用程序是一个 Java 应用程序。 如果我将 Java 应用程序直接绑定到服务器应用程序端口,则延迟非常低,但如果我将其连接到中继应用程序端口,我会得到将近一秒的延迟。 接收端口必须是非阻塞的。
#define rcv_length 160
fd_set fds;
int n;
struct timeval tv;
void CMClient::startUDPListener(){
CMport_number = 32200;
remoteAddrLen = sizeof(struct sockaddr_in);
if (WSAStartup(0x0101, &CMw) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
CMsd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (CMsd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
CMserver.sin_family = AF_INET;
CMserver.sin_port = htons(CMport_number);
CMserver.sin_addr.s_addr = inet_addr("127.0.0.1");
long rc=bind(CMsd,(SOCKADDR*)&CMserver,sizeof(SOCKADDR_IN));
if(rc==SOCKET_ERROR)
{
printf("Error: bind code: %d\n",WSAGetLastError());
}
}
void CMClient::updateData(UDPServer* svr, int CMnr){
FD_ZERO(&fds);
FD_SET(CMsd, &fds);
tv.tv_sec = 0;
tv.tv_usec = 1;
n = select ( CMsd, &fds, NULL, NULL, &tv ) ;
if (FD_ISSET(CMsd, &fds))
{
FD_CLR(CMsd,&fds);
char* rcvBuffer = new char[rcv_length];
long rc=recv(CMsd,rcvBuffer,rcv_length,0); //receive
if(rc!=SOCKET_ERROR)
{
rcvBuffer[0] = CMnr;
sendto(svr->sd, (char*)rcvBuffer, rcv_length, 0, (struct sockaddr*)&svr->server, sizeof(svr->server)) != (int)sizeof(rcvBuffer); //send
}
if(rcvBuffer)
delete [] rcvBuffer;
}
}
发送到Java应用程序的UDP服务器初始化如下:
void UDPServer::startUDPServer(){
if (WSAStartup(0x0101, &w) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
server.sin_family = AF_INET;
server.sin_port = htons(port_number);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "Could not connect name to socket.\n");
stopUDPServer();
}
}
主要调用
UDPServer* udpsvr;
udpsvr = new UDPServer;
udpsvr->startUDPServer();
while(1){
CM->updateData(udpsvr, CMid);
}
任何帮助将不胜感激,为什么我会延迟这么多。 从 Java 应用程序接收到的数据是正确的,但有大约 1 秒的延迟。
谢谢你, 问候
【问题讨论】:
-
更相关的代码是读/写操作...
-
你是如何测量延迟的?您能否测量各个阶段的延迟(在中继应用中接收,从中继应用发送)?
-
读/写操作在第一个代码块的 if (FD_ISSET(CMsd, &fds)) 语句中完成。我只是在视觉上“测量”它。我有一个在 java 应用程序中移动的点。如果我将 java 应用程序直接连接到原始发件人,它会立即工作,如果连接到中继,它会延迟大约一秒钟。