Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 套接字编程代码在XP上执行,但在Windows 7上失败_C_Sockets_Windows 7_Cygwin_Windows Xp - Fatal编程技术网

C 套接字编程代码在XP上执行,但在Windows 7上失败

C 套接字编程代码在XP上执行,但在Windows 7上失败,c,sockets,windows-7,cygwin,windows-xp,C,Sockets,Windows 7,Cygwin,Windows Xp,首先,让我告诉你代码的目标。 它是一个udpserver,应该提供有关接收数据包数量和所用时间等的统计信息。客户端代码是公司嵌入式代码的一部分,不能共享。下面是代码 /* ** listener.c -- a datagram sockets "server" demo */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include

首先,让我告诉你代码的目标。 它是一个udpserver,应该提供有关接收数据包数量和所用时间等的统计信息。客户端代码是公司嵌入式代码的一部分,不能共享。下面是代码

/*
** listener.c -- a datagram sockets "server" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <netdb.h>
#include <time.h>
#include <math.h>
#include "windows.h"

#define MYPORT "4950"   // Default port number users will be connecting to

#define MAXBUFLEN 1497 

#define TIMEOUT_PERIOD_IN_SEC  5  /* Time out after the last packet reception */

//#define DEBUG_ENABLE

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(int argc, char *argv[]) 
{
    int sockfd;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    int numbytes=0;
    struct sockaddr_storage their_addr;
    char buf[MAXBUFLEN];
    socklen_t addr_len;
    char s[INET6_ADDRSTRLEN];
    int flag=1;
    struct timeval tv;
    fd_set rfds;
    int retval;
    long long  length = 0;
    double   totalTxBits=0;
    double   dataRate=0;

        FILETIME   sysTime;
        long long  startTime=0;
        long long  endTime=0;
        long long  timeDurationInMicSec;
    long total_no_of_packets=0;
    long expected_length=0;
        char portNum[8];
        int i;

       switch(argc)
       {
       case 2:
               {
                   strncpy(portNum, argv[1],8);

                   if((0==strcmp(portNum,"-h")) || (0==strcmp(portNum,"h")))
                   {
                       printf("\r\nUsage: \r\n\t udpserver.exe [<port num>] [<expected length(bytes)>]\r\n");
                       printf("\r\nNote: All parameters are optional\r\n");
                       printf("\r\nExample: \r\n\t i) udpserver.exe \r\n");
                       printf("\n\t ii) udpserver.exe 8000 \r\n");
                       printf("\n\t iii) udpserver.exe 8000 100000\r\n");
                       printf("\n\t iv) udpserver.exe 8000 100000 1400\r\n");

                       return 1;
                   }

                   // Make sure that argument contains nothing but digits
                   for (i = 0; i < strlen(portNum); i++)
                   {
                       if (!isdigit(portNum[i]))
                       {
                           printf("\r\n Invalid port number \r\n");
                           printf("\r\nUsage: \r\n\t udpserver.exe [<port num>] [<expected length>]\r\n");
                            return 1;
                       }
                   }

               }
           break;

       case 3:
            {
               strncpy(portNum, argv[1],8);

               /* Make sure that argument contains nothing but digits */
               for (i = 0; i < strlen(portNum); i++)
               {
                   if (!isdigit(portNum[i]))
                   {
                       printf("\r\n Invalid port number \r\n");
                       return 1;
                   }
               }

               printf("\r\nExpected length                 :%d \r\n",atoi(argv[2]));
               expected_length = atoi(argv[2]);
            }
        break;

           case 4:
            {
               strncpy(portNum, argv[1],8);

                /* Make sure that argument contains nothing but digits */
               for (i = 0; i < strlen(portNum); i++)
               {
                   if (!isdigit(portNum[i]))
                   {
                       printf("\r\n Invalid port number \r\n");
                       return 1;
                   }
               }


               expected_length = atoi(argv[2]);
               expected_length  = expected_length * atoi(argv[3]);
               printf("\r\nExpected length                 :%d (%d x %d)\r\n",expected_length,atoi(argv[2]),atoi(argv[3]));
           }
       break;

       default:
       {   
           strcpy(portNum, MYPORT);
               expected_length=0;
       }
       break;
       }

       printf("\r\nWaiting on port number          :%s \r\n",portNum);

       tv.tv_sec = TIMEOUT_PERIOD_IN_SEC; /* Time out after the last packet reception */
       tv.tv_usec = 0;

       memset(&hints, 0, sizeof hints);
       hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
       hints.ai_socktype = SOCK_DGRAM;
       hints.ai_flags = AI_PASSIVE; // use my IP

       if ((rv = getaddrinfo(NULL, portNum, &hints, &servinfo)) != 0) {
           fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
       return 1;
       }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("listener: socket");
            continue;
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("listener: bind");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "listener: failed to bind socket\n");
        return 2;
    }

    freeaddrinfo(servinfo);

    total_no_of_packets=0;

    while(flag)
    {

#ifdef DEBUG_ENABLE
        printf("listener: waiting to recvfrom...\n");
#endif /* DEBUG_ENABLE */

        addr_len = sizeof their_addr;

        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
            (struct sockaddr *)&their_addr, &addr_len)) == -1)
        {
            perror("recvfrom");
            exit(1);
        }

        total_no_of_packets++;

#ifdef DEBUG_ENABLE
        printf("listener: got packet from %s\n",
        inet_ntop(their_addr.ss_family,
        get_in_addr((struct sockaddr *)&their_addr),
        s, sizeof s));
#endif /* DEBUG_ENABLE */

        if (0==length)
        {
            GetSystemTimeAsFileTime(&sysTime);
            startTime = sysTime.dwHighDateTime;
            startTime =  (startTime<<32) | sysTime.dwLowDateTime; /* number of 100-nanosecond intervals  */

        }

#ifdef DEBUG_ENABLE
        printf("listener: packet is %d bytes long\n", numbytes);
#endif /* DEBUG_ENABLE */
        length+=numbytes;

        #if 0
        GetSystemTimeAsFileTime(&sysTime);
        endTime =sysTime.dwHighDateTime;
        endTime =  (endTime<<32) | sysTime.dwLowDateTime; /* number of 100-nanosecond intervals  */
        #endif

        buf[numbytes] = '\0';

#ifdef DEBUG_ENABLE     
        printf("listener: packet contains \"%s\"\n", buf);
#endif /* DEBUG_ENABLE */

        FD_ZERO(&rfds);
        FD_SET(sockfd, &rfds);
        retval = select(sockfd+1, &rfds, NULL, NULL, &tv);

        if (retval == 0)
        {   
            GetSystemTimeAsFileTime(&sysTime);
                    endTime =sysTime.dwHighDateTime;
            endTime =  (endTime<<32) | sysTime.dwLowDateTime; /* number of 100-nanosecond intervals  */
                    timeDurationInMicSec  =(endTime - startTime) / (long long)10;

                     /* Subtract the last time-out value  */
                   if(timeDurationInMicSec)
                   {
                       timeDurationInMicSec -= ((long long)(TIMEOUT_PERIOD_IN_SEC *1000*1000));
                   }

                   printf("\r\n$Time taken                     :%ld micro sec\r\n",timeDurationInMicSec);

                   /* Convert to bits */
                   totalTxBits = length*8;

                   if(timeDurationInMicSec)
                   {
                       dataRate = (totalTxBits*1000*1000)/timeDurationInMicSec;
                   }

                   if(dataRate)
                   {
                       printf("$Number of packets recieved     :%lld\r\n",(total_no_of_packets));
                       printf("$Total number of bytes recieved :%lld\r\n",(length));

                       printf("\r\n$DataRate                       :%f bits per sec\n",dataRate);
                       printf("\r\n$DataRate                       :%f kbps (kilo bits per sec)\n",(dataRate/1024));

                       printf("\r\nNet throughput                  :%f mbps (mega bits per sec)\n",(dataRate/(1024*1024)));

                       if(0 != expected_length)
                       {
                           if(expected_length >= length)
                           {
                               printf("\r\nData loss                       :%lld bytes ( %f percentage)",(expected_length - length), ((float)((expected_length - length)*100))/(float)expected_length);
                           }
                       }

                   }
                   else
                   {
                       printf("$Error: Unable to calculate throughput.");
                   }

            break;
        }

    }

    close(sockfd);
    return 0;
}
在线191

我尝试使用XP SP3兼容性和管理员权限运行可执行文件。我试着上网,但没有找到解决办法。有人知道我在编译过程中是否犯了错误吗?我做了一个简单的测试

gcc -o udpserver.exe udpserver.c
这是成功的。请让我知道我能做些什么来进一步缩小这个问题。我对socket编程和genenral编程还是相当陌生的


提前谢谢

如果要搜索要绑定到的地址,例如通过getaddrinfo,通常需要绑定到找到的所有地址。否则,在具有多个适配器的计算机上,您的服务将仅在随机选择的单个适配器上可用;即使只有一个适配器,您也可能绑定到错误的协议,如本例所示

我认为通常的方法是绑定到任意地址,IPv4中的0.0.0.0,如中所述:

如果应用程序不关心分配的本地地址,请在name参数的sa_数据成员中为IPv4本地地址指定INADR_ANY常量值,或为IPv6本地地址指定6ADDR_ANY常量值


客户端是在同一台机器上运行,还是在网络上运行?如果客户端在网络上,您是否记得配置防火墙?抱歉,我花了一些时间才做出响应。我昨天因其他工作被解雇了。我今天尝试禁用防火墙。同样的问题。我发现您只绑定到找到的第一个地址/协议;可能是在客户端需要IPv4时绑定到IPv6,或者可能是绑定到错误的地址,例如127.0.0.1或某个隧道适配器?您可以使用netstat-a-n-b检查绑定,或者向代码中添加适当的诊断。您完全正确。Netstat确实揭示了这个问题。我不知道我为什么要用AF_Unsec家族。我刚把它改成AF_INET,它就成功了。显然,Windows7优先考虑ipv6而不是ipv4。非常感谢。如果你对此作出答复,我将把它标记为已接受。
gcc -o udpserver.exe udpserver.c