На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
    > nonblocking sockets C (си) , connect () failed: no error
      доброго времени суток, уважаемые.
      писал программку на Си - что то отдалённо напоминающее хттп клиент
      должна отправаить запрос и принимть ответы сервера.
      доп зависимости в линкере wsock32.lib Ws2_32.lib
      ExpandedWrap disabled
        #include <stdio.h>      /* for printf(), fprintf() */
        #include <winsock.h>    /* for socket(),... */
        #include <stdlib.h>     /* for exit() */
         
        #define RCVBUFSIZE 32   /* Size of receive buffer */
         
        void DieWithError(char *errorMessage){
            perror(errorMessage);
            exit(0);
        };  /* Error handling function */
         
        void main(int argc, char *argv[])
        {
            int sock;                        /* Socket descriptor */
            struct sockaddr_in echoServAddr; /* Echo server address */
            unsigned short echoServPort;     /* Echo server port */
            char *servIP;                    /* Server IP address (dotted quad) */
            
            char echoString[]= "identifier=1z2y3z \r\n\r\n";
            char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
            int echoStringLen;               /* Length of string to echo */
            int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() and total bytes read */
            WSADATA wsaData;                 /* Structure for WinSock setup communication */
            unsigned long nonblocking = 1;
            if ((argc < 2) || (argc > 3))    /* Test for correct number of arguments */
            {
                fprintf(stderr, "Usage: %s <Server IP> <Echo Port>\n", argv[0]);
                exit(1);
            }
         
            servIP = argv[1];             /* First arg: server IP address (dotted quad) */
          echoServPort = argv[2];         /* Second arg: server port */
         
          
            if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
            {
                fprintf(stderr, "WSAStartup() failed");
                exit(1);
            }
         
            /* Create a reliable, stream socket using TCP */
            if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
                DieWithError("socket() failed");
         
            /* Set the socket to nonblocking */
            if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
                DieWithError("ioctlsocket() failed");
         
            /* Construct the server address structure */
            memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
            echoServAddr.sin_family      = AF_INET;             /* Internet address family */
            echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
            echoServAddr.sin_port        = htons(echoServPort); /* Server port */
            /* Establish the connection to the echo server */
            if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
                DieWithError("connect() failed");
         
            echoStringLen = strlen(echoString);          /* Determine input length */
         
            /* Send the string, including the null terminator, to the server */
            if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
                DieWithError("send() sent a different number of bytes than expected");
         
            /* Receive the same string back from the server */
            totalBytesRcvd = 0;
            printf("Received: ");                /* Setup to print the echoed string */
            while (totalBytesRcvd < echoStringLen)
            {
                /* Receive up to the buffer size (minus 1 to leave space for
                   a null terminator) bytes from the sender */
                if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
                    DieWithError("recv() failed or connection closed prematurely");
                totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
                echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
                printf("%s", echoBuffer);            /* Print the echo buffer */
            }
         
            printf("\n");    /* Print a final linefeed */
         
            closesocket(sock);
            WSACleanup();  /* Cleanup Winsock */
         
            exit(0);
        }

      при коннекте "program.exe host port"
      ошибка соединения, почему не понимаю
      connect () failed: no error
      прошу помощи в разъяснении
      Сообщение отредактировано: sign63 -
        Цитата
        If no error occurs, connect returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.

        On a blocking socket, the return value indicates success or failure of the connection attempt.


        With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK. In this case, there are three possible scenarios:

        Use the select function to determine the completion of the connection request by checking to see if the socket is writeable.
        If the application is using WSAAsyncSelect to indicate interest in connection events, then the application will receive an FD_CONNECT notification indicating that the connect operation is complete (successfully or not).
        If the application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not).


        Короче, в неблокирующем режиме, он может сразу не подключиться, возвращая WSAEWOULDBLOCK. Всго лишь нужно подождать, либо использовать select для того, чтобы убедиться в завершенности операции.
          в смысле подождать
            Если программа несерьезная, можно вставить sleep после connect, когда - нибудь соединение да произойдет, если сервер доступен.
            Но лучше так не делать и использовать WSAAsyncSelect c флагом события FD_CONNECT.
              поменял
              ExpandedWrap disabled
                echoServPort = argv[2];

              на
              ExpandedWrap disabled
                echoServPort = atoi(argv[2]);

              ExpandedWrap disabled
                ..
                #include <unistd.h>
                ..
                ..
                /* Create a reliable, stream socket using TCP */
                    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0)
                        DieWithError("socket() failed");
                 
                sleep(5);
                 
                 
                    /* Set the socket to nonblocking */
                    if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
                        DieWithError("ioctlsocket() failed");
                 
                ..
                ..

              Не удается открыть файл include: unistd.h: No such file or directory
              Этж только под никсами... а на мастдае как?

              и еще: как с WSAAsyncSelect сделать? можно на примере моей проги показать?
              Или киньте ссылку, где подробно расписано о WSAAsyncSelect для Си
              Сообщение отредактировано: sign63 -
                подправил. теперь c select. ждет 2.5 секунды и выходит :D
                Программа "[2312] у3к6.exe: Машинный код" завершилась с кодом 0 (0x0).
                ExpandedWrap disabled
                  #include <stdio.h>      /* for printf(), fprintf() */
                  #include <winsock.h>    /* for socket(),... */
                  #include <stdlib.h>     /* for exit() */
                  #include <time.h>
                  #include <sys/types.h>
                   
                  #define RCVBUFSIZE 32   /* Size of receive buffer */
                   
                  void DieWithError(char *errorMessage){
                      perror(errorMessage);
                      exit(0);
                  };  /* Error handling function */
                   
                  void main(int argc, char *argv[])
                  {
                      int sock, rc, read_fds, echoServPort;                      
                      struct sockaddr_in echoServAddr;
                  //    unsigned short echoServPort;    
                      char *servIP;                    
                      char echoString[]= "identifier=1z2y3z \r\n\r\n";
                      char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
                      int echoStringLen;               /* Length of string to echo */
                      int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() and total bytes read */
                      WSADATA wsaData;                 /* Structure for WinSock setup communication */
                      unsigned long nonblocking = 1;
                      struct timeval tv;
                      fd_set readfds;
                      tv.tv_sec = 2;
                      tv.tv_usec = 500000;
                    
                      servIP = argv[1];             /* First arg: server IP address (dotted quad) */
                    
                      // echoServPort = atoi(argv[2]); /* Use given port, if any */
                    echoServPort = 8088;
                      if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
                      {
                          fprintf(stderr, "WSAStartup() failed");
                          exit(1);
                      }
                   
                      /* Create a reliable, stream socket using TCP */
                      if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0)
                          DieWithError("socket() failed");
                   
                      /* Set the socket to nonblocking */
                      if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
                          DieWithError("ioctlsocket() failed");
                   
                      /* Construct the server address structure */
                      memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
                      echoServAddr.sin_family      = AF_INET;             /* Internet address family */
                      echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
                      echoServAddr.sin_port        = htons(echoServPort); /* Server port */
                      
                      FD_ZERO(&readfds);
                      FD_SET(sock, &readfds);
                      rc = select(sock, &readfds, NULL, NULL, &tv);
                      if((rc == 1) && (FD_ISSET(sock, &read_fds)))
                  {
                      /* Establish the connection to the echo server */
                      if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
                          DieWithError("connect() failed");
                      
                      echoStringLen = strlen(echoString);          /* Determine input length */
                   
                      /* Send the string, including the null terminator, to the server */
                      if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
                          DieWithError("send() sent a different number of bytes than expected");
                   
                      /* Receive the same string back from the server */
                      totalBytesRcvd = 0;
                      printf("Received: ");                /* Setup to print the echoed string */
                      while (totalBytesRcvd < echoStringLen)
                      {
                          /* Receive up to the buffer size (minus 1 to leave space for
                             a null terminator) bytes from the sender */
                          if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
                              DieWithError("recv() failed or connection closed prematurely");
                          totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
                          echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
                          printf("%s", echoBuffer);            /* Print the echo buffer */
                      }
                      }
                   
                   
                      printf("\n");    /* Print a final linefeed */
                   
                      closesocket(sock);
                      WSACleanup();  /* Cleanup Winsock */
                   
                      exit(0);
                  }
                  Ты бы поспал :)
                  В твоем случае
                  rc = select(sock, &readfds, NULL, NULL, &tv);
                  ожидает, когда в сокет придут данные, сокет, который даже не подключен (connect ниже).
                  select нужно использовать не для ожидания того, когда он будет готов для чтения, а для ожидания того, когда он будет готов для записи. А это другой параметр.
                  удачи!
                    :wall: таже фигня
                    ExpandedWrap disabled
                      #include <stdio.h>      /* for printf(), fprintf() */
                      #include <winsock.h>    /* for socket(),... */
                      #include <stdlib.h>     /* for exit() */
                      #include <time.h>
                      #include <sys/types.h>
                       
                      #define RCVBUFSIZE 32   /* Size of receive buffer */
                       
                      void DieWithError(char *errorMessage){
                          perror(errorMessage);
                          exit(0);
                      };  /* Error handling function */
                       
                      void main(int argc, char *argv[])
                      {
                          int sock, rc;                        /* Socket descriptor */
                          struct sockaddr_in echoServAddr; /* Echo server address */
                          unsigned short echoServPort;     /* Echo server port */
                          char *servIP;                    /* Server IP address (dotted quad) */
                          char echoString[]= "identifier=1z2y3z \r\n\r\n";
                          char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
                          int echoStringLen;               /* Length of string to echo */
                          int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() and total bytes read */
                          WSADATA wsaData;                 /* Structure for WinSock setup communication */
                          unsigned long nonblocking = 1;
                          fd_set writefds;
                          struct timeval tv;
                          tv.tv_sec = 2;
                          tv.tv_usec = 500000;
                          servIP =  argv[1];             /* First arg: server IP address (dotted quad) */
                          echoServPort =  atoi(argv[2]);  /* Use given port, if any */
                          if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
                          {
                              fprintf(stderr, "WSAStartup() failed");
                              exit(1);
                          }
                       
                          /* Create a reliable, stream socket using TCP */
                          if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0)
                              DieWithError("socket() failed");
                        
                       
                          /* Set the socket to nonblocking */
                          if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
                              DieWithError("ioctlsocket() failed");
                       
                          /* Construct the server address structure */
                          memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
                          echoServAddr.sin_family      = AF_INET;             /* Internet address family */
                          echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
                          echoServAddr.sin_port        = htons(echoServPort); /* Server port */
                          
                          FD_ZERO(&writefds);
                          FD_SET(sock, &writefds);
                          rc = select(sock, NULL, &writefds, NULL, &tv);
                          if((rc == 1) && (FD_ISSET(sock, &writefds)))
                      {
                          /* Establish the connection to the echo server */
                          if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
                              DieWithError("connect() failed");
                          
                          echoStringLen = strlen(echoString);          /* Determine input length */
                       
                          /* Send the string, including the null terminator, to the server */
                          if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
                              DieWithError("send() sent a different number of bytes than expected");
                       
                          /* Receive the same string back from the server */
                          totalBytesRcvd = 0;
                          printf("Received: ");                /* Setup to print the echoed string */
                          while (totalBytesRcvd < echoStringLen)
                          {
                              /* Receive up to the buffer size (minus 1 to leave space for
                                 a null terminator) bytes from the sender */
                              if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
                                  DieWithError("recv() failed or connection closed prematurely");
                              totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
                              echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
                              printf("%s", echoBuffer);            /* Print the echo buffer */
                          }
                          }
                       
                       
                          printf("\n");    /* Print a final linefeed */
                       
                          closesocket(sock);
                          WSACleanup();  /* Cleanup Winsock */
                       
                          exit(0);
                      }
                      Цитата sign63 @
                      ...
                      ExpandedWrap disabled
                        ...
                            while (totalBytesRcvd < echoStringLen)
                            {
                        ....
                                if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
                        ...
                                totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
                                echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
                        ..
                            }
                        ...

                      не понятна следующая логика.
                      1) цикл на общую длину.
                      2) идёт перезатирка ранее принятых данных.

                      так вам что нуна то?
                      Приём по кусочкам на которые раздробил данные нижний уровень(или вы в передатчике) или приём полной длины эхо строки?

                      это не будет понятно пока у вас строка маленькая, работаете не в боевой сети и на нагрузках типа хэлохты мир.

                      увеличьте строку скажем до пары метров.


                      удачи вам
                      (круглый)
                        Цитата kolobok0 @
                        Цитата sign63 @
                        ...
                        ExpandedWrap disabled
                          ...
                              while (totalBytesRcvd < echoStringLen)
                              {
                          ....
                                  if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
                          ...
                                  totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
                                  echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
                          ..
                              }
                          ...

                        не понятна следующая логика.
                        1) цикл на общую длину.
                        2) идёт перезатирка ранее принятых данных.

                        так вам что нуна то?
                        Приём по кусочкам на которые раздробил данные нижний уровень(или вы в передатчике) или приём полной длины эхо строки?

                        это не будет понятно пока у вас строка маленькая, работаете не в боевой сети и на нагрузках типа хэлохты мир.

                        увеличьте строку скажем до пары метров.


                        удачи вам
                        (круглый)

                        над приемом данных еще подумаю, но проблема сейчас пока что в коннекте к серверу, надо её сначало решить
                        Сообщение отредактировано: sign63 -
                          Цитата sign63 @
                          доп зависимости в линкере wsock32.lib Ws2_32.lib

                          Зачем линкуете сразу две библиотеки?
                          Вы работаете с версией винсок 2.0

                          (WSAStartup(MAKEWORD(2, 0), &wsaData)

                          - потому только Ws2_32.lib
                          и еще - winsock2.h
                            Цитата Oleg2004 @
                            Цитата sign63 @
                            доп зависимости в линкере wsock32.lib Ws2_32.lib

                            Зачем линкуете сразу две библиотеки?
                            Вы работаете с версией винсок 2.0

                            (WSAStartup(MAKEWORD(2, 0), &wsaData)

                            - потому только Ws2_32.lib
                            и еще - winsock2.h

                            просто были траблы на ранней части написания, в каком то из мануалов вымсмотрел.
                            убрал лишнюю wsock32.lib, поправил winsock.h на winsock2.h

                            нашёл WWinsock Interface Library for C/C++ 3.1
                            там куча примеров, есть то что мне надо async.c
                            но не компилируется, зараза в visual studio. по идее такие как эти проекты (стоимость 130$ на офф сайте)
                            должны сразу без проблем компилится

                            Цитата
                            Компиляция...
                            ASYNC.C
                            z:\wil4c\ASYNC.C(69) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR'
                            z:\wil4c\ASYNC.C(69) : warning C4133: функция: несовместимые типы - из 'char [17]' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(95) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR'
                            z:\wil4c\ASYNC.C(95) : warning C4133: функция: несовместимые типы - из 'char [29]' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(146) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR'
                            z:\wil4c\ASYNC.C(146) : warning C4133: функция: несовместимые типы - из 'char [17]' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(167) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR'
                            z:\wil4c\ASYNC.C(167) : warning C4133: функция: несовместимые типы - из 'char [25]' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(176) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(192) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPWSTR'
                            z:\wil4c\ASYNC.C(192) : warning C4133: функция: несовместимые типы - из 'char [30]' в 'LPCWSTR'
                            z:\wil4c\ASYNC.C(202) : warning C4133: функция: несовместимые типы - из 'LPSTR' в 'LPCWSTR'
                            Компоновка...
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilTcpSocket@0"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilMakeAddr@4"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilErrorText@12"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilReadLine@12"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilGetHostAddr@8"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "_DisplayLine"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilIsDotted@4"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilMakeDotted@12"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilWriteLine@8"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "_StringCopy"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "_DisplayString"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilConnect@12"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilParseDecimal@4"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilWaitLine@20"
                            ASYNC.obj : error LNK2001: неразрешенный внешний символ "__imp__wilAwaitEvent@16"
                            MSVCRT.lib(crtexe.obj) : error LNK2001: неразрешенный внешний символ "_main"


                            а miracle C ругается только на
                            Цитата
                            wil.h: line 71: Parse Error, expecting `','' or `SEP'
                            'SOCKET FAR'
                            aborting compile
                              select возвращает 0, что говорит о истекшем тайм ауте
                              а значения sin_port, echoServAddr.sin_port разве должны быть такими?
                              user posted image
                                Цитата sign63 @
                                а значения sin_port, echoServAddr.sin_port разве должны быть такими?

                                Они преобразованы ы порядок сети - а выводятся в порядке хоста.
                                  как сказал мне один форумчанин:
                                  Цитата
                                  в данной ситуации позволяет дождаться, когда будет закончено выполнение предыдущей операции. Пока коннект с сервером не установлен, ни о какой отправке данных речи быть не может, поэтому ждём:select (sock, NULL, &writefds, NULL, &tv); потом говорим write, и хотим прочитать ответ. Но пока ответ не пришёл, читать бессмысленно. Поэтому select (sock, &readfds, NULL, NULL, &tv); и только потом read.
                                  Сообщение отредактировано: sign63 -
                                  1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                  0 пользователей:
                                  Страницы: (3) [1] 2 3  все


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,1122 ]   [ 15 queries used ]   [ Generated: 19.05.24, 02:49 GMT ]