2010-10-05 65 views
0

我是套接字编程的初学者。我想从端口连续接收udp数据包。为此,我创建了套接字并使用bind和recv调用了我的程序。在缓冲区中,我正在存储udp数据包。如何接收数据包。如何把特定时间间隔的条件?提前致谢。udp winsock编程

static int recvData = 1; 
sockID = socket(AF_INET, SOCK_DGRAM, 0); 
if(sockID < 0) 
{ 
    printf("Socket creation error\n"); 
     WSACleanup(); 
} 
else 
{ 
    printf("Socket Created\n"); 
} 

fepAddr.sin_family = AF_INET; 
fepAddr.sin_port = htons(inputData.portNo); 
fepAddr.sin_addr.s_addr = inet_addr(inputData.destIPAddr); 

if (bind(sockID, (struct sockaddr *)&fepAddr, sizeof(fepAddr)) == SOCKET_ERROR) 
{ 
    printf("bind() failed: %ld.\n", WSAGetLastError()); 
    closesocket(sockID); 
    return 0; 
} 

else 
{ 
    printf("bind() is OK!\n"); 
} 

memset(udpBuf,sizeof(udpBuf),0); 
while (recvData) 
{ 
    printf("receiving data\n"); 
    recvResult = recvfrom(sockID, udpBuf, sizeof(udpBuf), 0,(struct sockaddr *)&fepAddr, &sock_len); 


    fprintf(udp, "%s", udpBuf); 
    //fwrite(udpBuf, sizeof(udpBuf), 1, udp); 
    recvData-- ; 
} 
exit: 
    if(udp) 
    { 
     fclose(udp); 
     udp = 0; 
    } 

//shutdown socket 
closesocket(sockID); 
fclose(udp); 

回答

1

recvfrom()逐包地接收UDP数据。如果给定的数据包太大,recvfrom()将返回一个错误。至于时机,你可以使用select()来知道套接字何时可读。

尝试是这样的:

sockID = socket(AF_INET, SOCK_DGRAM, 0); 
if (sockID == INVALID_SOCKET) 
{ 
    printf("Socket creation error\n"); 
    goto exit; 
} 

printf("Socket Created\n"); 

memset(&fepAddr, 0, sizeof(fepAddr)); 
fepAddr.sin_family = AF_INET; 
fepAddr.sin_port = htons(inputData.portNo); 
fepAddr.sin_addr.s_addr = inet_addr(inputData.destIPAddr); 

if (bind(sockID, (struct sockaddr *)&fepAddr, sizeof(fepAddr)) == SOCKET_ERROR) 
{ 
    printf("bind() failed: %ld.\n", WSAGetLastError()); 
    goto exit; 
} 

printf("bind() is OK!\n"); 

memset(udpBuf, 0, sizeof(udpBuf)); 

printf("receiving data\n"); 
while (...) 
{ 
    printf("."); 

    recvResult = recvfrom(sockID, udpBuf, sizeof(udpBuf), 0, (struct sockaddr *)&fepAddr, &addr_len); 
    if (recvResult == SOCKET_ERROR) 
    { 
    if (WSAGetLastError() != WSAEWOULDBLOCK) 
    { 
     printf("\nrecvfrom() failed: %ld.\n", WSAGetLastError()); 
     goto exit; 
    } 

    fd_set fd; 
    FD_ZERO(&fd); 
    FD_SET(sockID, &fd); 

    timeval t; 
    t.tv_sec = ...; // seconds 
    t.tv_usec = ...; // microseconds 

    selectResult = select(0, &fd, NULL, NULL, &t); 
    if (selectResult == SOCKET_ERROR) 
    { 
     printf("\nselect() failed: %ld.\n", WSAGetLastError()); 
     goto exit; 
    } 

    if (selectResult == 0) 
    { 
     printf("\nsocket timed out.\n"); 
     goto exit; 
    } 

    continue; 
    } 

    if (recvResult > 0) 
    fwrite(udpBuf, recvResult, 1, udp); 
} 

exit: 
    if (udp != 0) 
    { 
    fclose(udp); 
    udp = 0; 
    } 

    if (sockID != INVALID_SOCKET) 
    { 
    closesocket(sockID); 
    sockID = INVALID_SOCKET; 
    } 
+0

感谢您的回复...... – ulaga 2010-10-06 04:37:22

+0

我需要一个更多的帮助.....我已创建使用套接字原始套接字(PF_PACKET,SOCK_RAW,ETH_P_IP) ....但它给无效的参数...如何创建原始套接字从端口接收udp数据包? – ulaga 2010-10-06 04:42:33

+0

SOCK_RAW不能在PF_PACKET系列中使用。它仅在AF_INET和AF_INET6系列中可用。即使端口不可用, – 2010-10-06 19:45:59