На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > 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 -
                                    Цитата sign63 @
                                    не открывается соединение.

                                    char servIP[] = "10.42.43.1";
                                    Этот IP - где он находится? В вашей локальной сети?
                                    И после connect() обязательно поставить WSAGetLastError() - без кода ошибки при соединении - узнать истинную причину невозможно.
                                    Это закон сетевого программирования - WSAGetLastError() после каждой сетевой функции.
                                    Например:
                                    r = recv(...);
                                    if (r == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
                                      Слабо поменять местами?
                                      Вот так:
                                      ExpandedWrap disabled
                                        {
                                            /* Establish the connection to the echo server */
                                            if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
                                                rc = select(sock, NULL, &writefds, NULL, &tv);
                                                 if((rc == 1) && (FD_ISSET(sock, &writefds)))
                                                  {printf("УРА!");}
                                                 else
                                        //        DieWithError("connect() failed");
                                            }
                                        Цитата Oleg2004 @
                                        Цитата sign63 @
                                        не открывается соединение.

                                        char servIP[] = "10.42.43.1";
                                        Этот IP - где он находится? В вашей локальной сети?
                                        И после connect() обязательно поставить WSAGetLastError() - без кода ошибки при соединении - узнать истинную причину невозможно.
                                        Это закон сетевого программирования - WSAGetLastError() после каждой сетевой функции.
                                        Например:
                                        r = recv(...);
                                        if (r == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)

                                        это ip хоста внутренней сети для доступа winxp из виртуалки к серверу на убунте (хосту)
                                        Добавлено
                                        Цитата Паровоз @
                                        Слабо поменять местами?
                                        Вот так:
                                        ExpandedWrap disabled
                                          {
                                              /* Establish the connection to the echo server */
                                              if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
                                                  rc = select(sock, NULL, &writefds, NULL, &tv);
                                                   if((rc == 1) && (FD_ISSET(sock, &writefds)))
                                                    {printf("УРА!");}
                                                   else
                                          //        DieWithError("connect() failed");
                                              }

                                        я сначала не заметил вторую страницу, решил проблему - сделал также как ты написал.
                                        Сообщение отредактировано: sign63 -
                                          кто здесь, кто здесь??? :ph34r:
                                          вот почему
                                          Цитата
                                          With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, connect will return SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK.

                                          тоесть как только сокет стал неблокирующим, в любом случае connect обязан возвращать SOCKET_ERROR (!). Это значит, что процесс коннекта начался успешно.
                                          Короче, упрощаемся немного. Подобно эхо серверу - коннектимся на яндекс, на 80-й порт, шлем лабудень, получаем в ответ 400 и наслаждаемся. Пардон, пишу левой ногой без телячьих нежностей ввиду отсутсвия времени. Чуть покорячу приведенный код - увеличу буфер и напишу как нада коннектиться. Не пинать типа "а чё ты не проверил что коннект вернул сокет_еррор" и т.п. Все детали - мсдн.
                                          ExpandedWrap disabled
                                            #include <stdio.h>      /* for printf(), fprintf() */
                                            #include <winsock2.h>    /* for socket(),... */
                                            #include <stdlib.h>     /* for exit() */
                                            #include <time.h>
                                            #include <sys/types.h>
                                             
                                            #define RCVBUFSIZE 3200   /* 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 servIP[] = "93.158.134.8";
                                                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, readfds;
                                                struct timeval tv;
                                                tv.tv_sec = 5;
                                                tv.tv_usec = 500000;
                                                //servIP =  argv[1];             /* First arg: server IP address (dotted quad) */
                                                echoServPort = 80; //atoi(8088);  //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 */
                                             
                                                connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr));
                                             
                                                FD_ZERO(&writefds);
                                                FD_SET(sock, &writefds);
                                                rc = select(sock, NULL, &writefds, NULL, &tv);
                                             
                                                if((rc == 1) && (FD_ISSET(sock, &writefds))) {
                                                    printf("connect success\n");
                                                } else {
                                                    printf("connect error\n");
                                                return;
                                                }
                                             
                                                send(sock, "1234", 4, 0);// шлем лабудень
                                             
                                                FD_ZERO(&readfds);
                                                FD_SET(sock, &readfds);
                                                rc = select(sock, &readfds, NULL, NULL, &tv);
                                             
                                                printf("read\n");
                                             
                                             
                                                if((rc == 1) && (FD_ISSET(sock, &readfds))) { // получаем ответ и выводим на экран
                                                    bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
                                                    printf("received %d bytes\n", bytesRcvd);
                                                    printf("%s\n", echoBuffer);
                                                    } else {
                                                printf("read error\n");
                                                return;
                                                }
                                             
                                                WSACleanup();  // Cleanup Winsock
                                            }


                                          такая вот фигня..
                                          Собираем этот кайф прямо строчным компилятором
                                          Цитата
                                          G:\user\lim\temp11>cl fib.cpp Ws2_32.lib
                                          Microsoft ® 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
                                          Copyright © Microsoft Corp 1984-1998. All rights reserved.

                                          fib.cpp
                                          Microsoft ® Incremental Linker Version 6.00.8168
                                          Copyright © Microsoft Corp 1992-1998. All rights reserved.

                                          /out:fib.exe
                                          fib.obj
                                          Ws2_32.lib


                                          результат
                                          Цитата
                                          G:\user\lim\temp11>fib.exe
                                          connect success
                                          read
                                          received 166 bytes
                                          <html>
                                          <head><title>400 Bad Request</title></head>
                                          <body bgcolor="white">
                                          <center><h1>400 Bad Request</h1></center>
                                          <hr><center>nginx</center>
                                          </body>
                                          </html>
                                            Цитата nemez @

                                            Чтож ты раньше не пришел <_<
                                            а мсдн я смотрел, да. жаль там примеры на cpp
                                            Сообщение отредактировано: sign63 -
                                              Цитата
                                              я сначала не заметил вторую страницу, решил проблему - сделал также как ты написал.

                                              Я тебе с утра еще об этом написал. Ночью спать надо ;)
                                                Цитата nemez @
                                                результат
                                                Цитата
                                                G:\user\lim\temp11>fib.exe
                                                connect success
                                                read
                                                received 166 bytes
                                                <html>
                                                <head><title>400 Bad Request</title></head>
                                                <body bgcolor="white">
                                                <center><h1>400 Bad Request</h1></center>
                                                <hr><center>nginx</center>
                                                </body>
                                                </html>

                                                а результат приходит только когда сервер разорвет соединение :(
                                                Сообщение отредактировано: sign63 -
                                                  ответ неправильный. Щас напишу как оно есть на самом деле.

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

                                                  argp - это дворд

                                                  Винда:
                                                  ioctl( Socket, FIONREAD, &argp );
                                                  Линукс:
                                                  ioctlsocket( Socket, FIONREAD, &argp );

                                                  Далее:
                                                  if ( argp > 0 ) {
                                                  bytesLen = recv(Socket, Buffer, argp, 0 );
                                                  // ....... и далее что нужно
                                                  }

                                                  if ( argp == 0) {
                                                  close(asCallData[wChannel].sSrcSocket);
                                                  }

                                                  собственно так. Тоесть, если в сокете ноль байт - это значит что сообщение разорвано. В противном случае - там есть данные, их надо оттуда выгрести и обработать
                                                    @nemez откуда ты так хорошо знаешь winsock для Си? Рыл инет, колво литературы по этому предмету - стремится к нулю. А та что действительно хорошая - на английском, благо английский это не проблема

                                                    Добавлено
                                                    Цитата nemez @
                                                    Винда:
                                                    ioctl( Socket, FIONREAD, &argp );
                                                    Линукс:
                                                    ioctlsocket( Socket, FIONREAD, &argp );

                                                    только наоборот
                                                    Линукс:
                                                    ioctl( Socket, FIONREAD, &argp );
                                                    Мастдай:
                                                    ioctlsocket( Socket, FIONREAD, &argp );
                                                    Сообщение отредактировано: sign63 -
                                                      еще вспомним
                                                      fcntl(sockfd, F_SETFL, O_NONBLOCK);
                                                      вариантов масса.

                                                      Цитата
                                                      собственно так. Тоесть, если в сокете ноль байт - это значит что сообщение разорвано. В противном случае - там есть данные, их надо оттуда выгрести и обработать

                                                      Еще забыл про -1 в неблокирующих. Значит, что ничего не пришло.
                                                      ExpandedWrap disabled
                                                            fcntl(sockfd, F_SETFL, O_NONBLOCK);
                                                            buffer.i = 0;
                                                            while(! stop)
                                                            {
                                                                 nbytes = recv(sockfd, data, sizeof(data), 0);
                                                            switch(nbytes)
                                                            {
                                                                case -1:
                                                                case  0:
                                                                  if(errno != EAGAIN)
                                                                  {
                                                                      sprintf(msg, "READ: server: closed connection");
                                                                           if (close(sockfd))
                                                                         perror("CLOSE: ");
                                                                      }
                                                                  nanosleep(&req, NULL);
                                                                  break;
                                                                default:
                                                                            sprintf(msg, "socket: %d Bytes, err = %d\n", nbytes); // process data
                                                        .....

                                                      Примерно таким куском я обычно пользуюсь
                                                      Сообщение отредактировано: Паровоз -
                                                        Цитата nemez @
                                                        ответ неправильный. Щас напишу как оно есть на самом деле.

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

                                                        argp - это дворд

                                                        ioctlsocket( Socket, FIONREAD, &argp );

                                                        Далее:
                                                        if ( argp > 0 ) {
                                                        bytesLen = recv(Socket, Buffer, argp, 0 );
                                                        // ....... и далее что нужно
                                                        }

                                                        if ( argp == 0) {
                                                        close(asCallData[wChannel].sSrcSocket);
                                                        }

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

                                                        так отосланные данные всё равно показывается в клиенте после того, когда сервер рвет соединение. и прога на этом естессн выходит
                                                        а когда сервер не рвет соединение, клиент сначала говорит 'read' т.е. можно читать
                                                        сервер шлёт данные
                                                        клиент показывает read error по истечению таймаута
                                                        ExpandedWrap disabled
                                                          send(sock, "identifier=1z2y3z \r\n", 22, 0);// шлем лабудень
                                                              tv2.tv_sec = 7;
                                                              FD_ZERO(&readfds);
                                                              FD_SET(sock, &readfds);
                                                              rc = select(sock, &readfds, NULL, NULL, &tv2);
                                                              {printf("read\n");
                                                           
                                                              ioctlsocket( sock, FIONREAD, &argp);
                                                             if (argp==0) {
                                                             // противоположная сторона закрыла сокет или отвалилась
                                                             closesocket(sock);
                                                             printf("read error\n");
                                                             return;  
                                                             } else {
                                                             // в противном сдучае выдираем данные из сокета. Да, argp - количество байт, которые надо выдрать ресивом
                                                             bytesRcvd = recv(sock, echoBuffer, argp, 0);
                                                                 printf("received %d bytes\n", bytesRcvd);
                                                                printf("%s\n", echoBuffer);
                                                              
                                                             }}

                                                        необходимо асинхронное чтение:
                                                        Цитата
                                                        сервер отослал данные
                                                        клиент принял
                                                        клиент отобразил не порвав соединение
                                                        Сообщение отредактировано: sign63 -
                                                          Вот вам пример:
                                                          ExpandedWrap disabled
                                                            #include <stdio.h>
                                                            #include <winsock2.h>
                                                            // port to connect to
                                                            #define PORT 3490
                                                            // maximum ammount of data to receive
                                                            #define MAXDATASIZE 1000
                                                            int main(int argc, char* argv[])
                                                            {
                                                                struct hostent*     he;
                                                                struct sockaddr_in  addr;
                                                                int         sock, received;
                                                                char            buffer[MAXDATASIZE + 1];
                                                                WSADATA         wsa_data;
                                                                // check parameters count
                                                                if ( argc != 2 )
                                                                {
                                                                    fprintf( stderr, "Usage: client <hostname>\n" );
                                                                    exit( 1 );
                                                                }
                                                                // init win sock library
                                                                WSAStartup( MAKEWORD( 1, 1 ), &wsa_data );
                                                                // resolve host name
                                                                if ( ( he = gethostbyname( argv[1] ) ) == NULL )
                                                                {
                                                                    fprintf( stderr, "Failed to resolve host name\n" );
                                                                    exit( 1 );
                                                                }
                                                                // create socket
                                                                if ( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
                                                                {
                                                                    fprintf( stderr, "Failed creating socket\n" );
                                                                    exit( 1 );
                                                                }
                                                                // switch socket to non-blocking mode
                                                                unsigned long l = 1;
                                                                if ( ioctlsocket( sock, FIONBIO, &l ) != 0 )
                                                                {
                                                                    fprintf( stderr, "Failed setting socket to non-blocking mode\n" );
                                                                    closesocket( sock );
                                                                    exit( 1 );
                                                                }
                                                                //
                                                                memset( &addr, 0, sizeof( addr ) );
                                                                // set remote addres
                                                                addr.sin_family = AF_INET;
                                                                addr.sin_port   = htons( PORT );
                                                                addr.sin_addr   = *((struct in_addr*) he->h_addr_list[0]);
                                                                // connect to server
                                                                if ( connect( sock, (sockaddr*) &addr, sizeof( sockaddr ) ) == SOCKET_ERROR )
                                                                {
                                                                    int error = WSAGetLastError( );
                                                                    if ( ( error != WSAEWOULDBLOCK ) && ( error != WSAEINPROGRESS ) )
                                                                    {
                                                                        fprintf( stderr, "Failed connecting to remote host, %d\n", error );
                                                                        closesocket( sock );
                                                                        exit( 1 );
                                                                    }
                                                                }
                                                                //
                                                                fd_set read_set, error_set;
                                                                struct timeval tv;
                                                                // wait for a message
                                                                for ( ; ; )
                                                                {
                                                                    tv.tv_sec = 1;
                                                                    tv.tv_usec = 0;
                                                                    // fill sets
                                                                    FD_ZERO( &read_set );
                                                                    FD_ZERO( &error_set );
                                                                    FD_SET( sock, &read_set );
                                                                    FD_SET( sock, &error_set );
                                                                    //
                                                                    if ( select( sock + 1, &read_set, NULL, &error_set, &tv ) == 1 )
                                                                    {
                                                                        // check for error
                                                                        if ( FD_ISSET( sock, &error_set ) )
                                                                        {
                                                                            int error, error_len = sizeof( error );
                                                                            getsockopt( sock, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len );
                                                                            fprintf( stderr, "\nError on socket (error: %d)\n", error );
                                                                        }
                                                             
                                                                        // check for message
                                                                        if ( FD_ISSET( sock, &read_set ) )
                                                                        {
                                                                            // receive some data from server
                                                                            if ( ( received = recv( sock, buffer, MAXDATASIZE, 0 ) ) == SOCKET_ERROR )
                                                                            {
                                                                                fprintf( stderr, "Failed receiving data\n" );
                                                                            }
                                                                            else
                                                                            {
                                                                                buffer[received] = '\0';
                                                                                // display the message
                                                                                printf( "\nYep! I got a message: %s\n", buffer );
                                                                            }
                                                                        }
                                                             
                                                                        break;
                                                                    }
                                                                    printf( "." );
                                                                }
                                                                // close socket
                                                                closesocket( sock );
                                                                // and say good bye to the world
                                                                return 0;
                                                            }


                                                          Добавлено
                                                          А вот это - нонсенс:
                                                          ExpandedWrap disabled
                                                            ioctlsocket( sock, FIONREAD, &argp);
                                                               if (argp==0) {
                                                               // противоположная сторона закрыла сокет или отвалилась
                                                               closesocket(sock);
                                                               printf("read error\n");
                                                               return;

                                                          argp - это аргумент команды - и его с нулем сравнивать?????????????

                                                          А для постоянного чтения - нужно висеть в цикле recv() - до получения нуля от сервера - т.е. сервер все передал - и больше не хочет с вами иметь дело :D - если буфер recv() не может принять всего сообщения сразу.
                                                          Или просто с большим буфером - ожидать всего сообщения и смотреть на ноль.....
                                                          Если в цикле есть select() - то его надо заново инициализировать...
                                                          В общем, надо "въехать" :) в протокол общения - если это например HTTP....
                                                            Цитата Oleg2004 @
                                                            Добавлено
                                                            А вот это - нонсенс:
                                                            ExpandedWrap disabled
                                                              ioctlsocket( sock, FIONREAD, &argp);
                                                                 if (argp==0) {
                                                                 // противоположная сторона закрыла сокет или отвалилась
                                                                 closesocket(sock);
                                                                 printf("read error\n");
                                                                 return;

                                                            argp - это аргумент команды - и его с нулем сравнивать?????????????

                                                            а как же аргумент &nonblocking у меня выше? у него же тоже есть значение. так же как и у &argp
                                                            Определить разрыв tcp соединение
                                                            сообщение №2

                                                            Добавлено
                                                            а чеит оно не комплится :blink:
                                                            Цитата
                                                            Компиляция...
                                                            winsock.c
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(35) : error C2143: синтаксическая ошибка: отсутствие ";" перед "тип"
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(36) : error C2065: l: необъявленный идентификатор
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(49) : error C2065: sockaddr: необъявленный идентификатор
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(49) : error C2059: синтаксическая ошибка: )
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(52) : error C2065: error: необъявленный идентификатор
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(52) : error C2065: error: необъявленный идентификатор
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(54) : error C2065: error: необъявленный идентификатор
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(60) : error C2061: синтаксическая ошибка: идентификатор "read_set"
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(60) : error C2059: синтаксическая ошибка: ;
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(60) : error C2059: синтаксическая ошибка: ,
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(63) : error C2059: синтаксическая ошибка: for
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(63) : error C2059: синтаксическая ошибка: )
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(64) : error C2449: имеется '{' в пределах области видимости файла (возможно, отсутствует заголовок функции)
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(102) : error C2059: синтаксическая ошибка: }
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(106) : error C2059: синтаксическая ошибка: return
                                                            ..\..\..\..\..\Рабочий стол\winsock.c(107) : error C2059: синтаксическая ошибка: }


                                                            Добавлено
                                                            эт чтобы посмотреть как на пример, а не реально работающая программка я так понял
                                                              Я не слышал о таком способе определения завершения TCP-сессии.
                                                              FIONREAD применяется для определения количества байтов, пришедших в буфер tcp-сокета.
                                                              При этом буфер не очищается.
                                                              Но значение нуля - в буфер никогда не помещается.
                                                              Это так сделан recv() - его реакция на сегмент FIN приводит к возврату нуля - но это никак не количество байтов - равное нулю!!!!!!!!!

                                                              Добавлено
                                                              У меня скомпилилась в момент :yes: - и это никакая не демо - а работающий клиент :angry:
                                                              Client\Client.cpp
                                                                Цитата Oleg2004 @
                                                                Добавлено
                                                                У меня скомпилилась в момент :yes: - и это никакая не демо - а работающий клиент :angry:
                                                                Client\Client.cpp

                                                                а так оно на C++ :( У меня клиент на си, попробую часть под себя подстроить
                                                                Сообщение отредактировано: sign63 -
                                                                  У Вас больше проблема с путями к заголовочным файлам. Потому и не компилится. А пример чистый С.
                                                                  Сообщение отредактировано: dikdik -
                                                                    Да особой разницы то я и не вижу - с и спп :D

                                                                    Добавлено
                                                                    Цитата dikdik @
                                                                    А пример чистый С.

                                                                    Это точно.....поэтому я и не видел разницы :D
                                                                    Чистый С в Студии компилится как спп без проблем.....во всяком случае у меня.
                                                                    А по ошибкам - да, видимо нет доступа к описанию элементарных типов......
                                                                      стартует, открывает соединение, ждет tv и выдает <cenzored>точек
                                                                      всё. поправил, теперь всё работает
                                                                      ExpandedWrap disabled
                                                                        #include <stdio.h>      /* for printf(), fprintf() */
                                                                        #include <winsock2.h>    /* for socket(),... */
                                                                        #include <stdlib.h>     /* for exit() */
                                                                        #include <time.h>
                                                                        #include <sys/types.h>
                                                                        #define MAXDATASIZE 1000
                                                                        #define RCVBUFSIZE 3200   /* 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 servIP[] = "10.0.2.2";
                                                                            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, readfds, error_set;
                                                                            struct timeval tv;
                                                                            tv.tv_sec = 5;
                                                                            tv.tv_usec = 500000;
                                                                            //servIP =  argv[1];             /* First arg: server IP address (dotted quad) */
                                                                            echoServPort = 8088; //atoi(8088);  //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 */
                                                                         
                                                                            connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr));
                                                                         
                                                                            FD_ZERO(&writefds);
                                                                            FD_SET(sock, &writefds);
                                                                            rc = select(sock, NULL, &writefds, NULL, &tv);
                                                                         
                                                                            if((rc == 1) && (FD_ISSET(sock, &writefds))) {
                                                                                printf("connect success\n");
                                                                            } else {
                                                                                printf("connect error\n");
                                                                            return;
                                                                            }
                                                                         
                                                                            send(sock, "identifier=1z2y3z \r\n\r\n", 26, 0);// шлем id
                                                                         
                                                                            
                                                                            for ( ; ; )
                                                                            {
                                                                               FD_ZERO(&readfds);
                                                                            FD_ZERO(&error_set);
                                                                            FD_SET(sock, &readfds);
                                                                            FD_SET(sock, &error_set);
                                                                                //
                                                                                if ( select( sock, &readfds, NULL, &error_set, &tv ) == 1 )
                                                                                {  
                                                                                    // check for error
                                                                                    if ( FD_ISSET( sock, &error_set ) )
                                                                                    {
                                                                                        int error, error_len = sizeof( error );
                                                                                        getsockopt( sock, SOL_SOCKET, SO_ERROR, (char*) &error, &error_len );
                                                                                        fprintf( stderr, "\nError on socket (error: %d)\n", error );
                                                                                    }
                                                                         
                                                                                    // check for message
                                                                                    if ( FD_ISSET( sock, &readfds ) )
                                                                                    {
                                                                                        // receive some data from server
                                                                                        if ( ( bytesRcvd = recv( sock, echoBuffer, MAXDATASIZE, 0 ) ) == SOCKET_ERROR )
                                                                                        {
                                                                                            fprintf( stderr, "Failed receiving data\n" );
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            echoBuffer[bytesRcvd] = '\0';
                                                                                            // display the message
                                                                                            printf( "\nYep! I got a message: %s\n", echoBuffer );
                                                                                        }
                                                                                    }
                                                                         
                                                                                    break;
                                                                                }
                                                                                printf( "." );
                                                                            }
                                                                          
                                                                            WSACleanup();  // Cleanup Winsock
                                                                        }

                                                                      user posted image
                                                                      Добавлено
                                                                      Цитата Oleg2004 @
                                                                      Да особой разницы то я и не вижу - с и спп :D

                                                                      Добавлено
                                                                      Цитата dikdik @
                                                                      А пример чистый С.

                                                                      Это точно.....поэтому я и не видел разницы :D
                                                                      Чистый С в Студии компилится как спп без проблем.....во всяком случае у меня.
                                                                      А по ошибкам - да, видимо нет доступа к описанию элементарных типов......

                                                                      Добавлено
                                                                      Цитата dikdik @
                                                                      У Вас больше проблема с путями к заголовочным файлам. Потому и не компилится. А пример чистый С.

                                                                      так я тоже думал что оно Си'шное. *.c не компилится, а с *.cpp компилится. Всё таки проблема с путями/доступом_к_описанию_элементарных_типов или то написано на C++?
                                                                      Сообщение отредактировано: sign63 -
                                                                        странно. У меня собирается как под расширением си, так и под расширением сипипи. Как под борландом, так и под майкрософтом.
                                                                        И приведенный код работает. Как это не странно. Я опять коннекчусь на яндекс, отправляю эту дребездень которая идентифаер стринг, и получаю 400й код.
                                                                        Из неправильного - перед каждым селектом надо делать FD_SET. Нужно обнулять массивы директивой FD_ZERO либо в конце основного цикла, либо в начале..
                                                                        короче, всю эту требуху
                                                                        Цитата
                                                                        FD_ZERO(&readfds);
                                                                        FD_ZERO(&error_set);
                                                                        FD_SET(sock, &readfds);
                                                                        FD_SET(sock, &error_set);

                                                                        нужно в основной цикл, сразу за фореву
                                                                          Цитата nemez @
                                                                          странно. У меня собирается как под расширением си, так и под расширением сипипи. Как под борландом, так и под майкрософтом.
                                                                          И приведенный код работает. Как это не странно. Я опять коннекчусь на яндекс, отправляю эту дребездень которая идентифаер стринг, и получаю 400й код.
                                                                          Из неправильного - перед каждым селектом надо делать FD_SET. Нужно обнулять массивы директивой FD_ZERO либо в конце основного цикла, либо в начале..
                                                                          короче, всю эту требуху
                                                                          Цитата
                                                                          FD_ZERO(&readfds);
                                                                          FD_ZERO(&error_set);
                                                                          FD_SET(sock, &readfds);
                                                                          FD_SET(sock, &error_set);

                                                                          нужно в основной цикл, сразу за фореву

                                                                          сбросы и сеты поправил.
                                                                          на яндексе код заработал. и на серве вроде тоже заработал.
                                                                          Сообщение отредактировано: sign63 -
                                                                            Цитата nemez @
                                                                            нужно в основной цикл, сразу за фореву

                                                                            Я как раз об этом предупреждал :yes:
                                                                            Это известная фишка селекта - после единственного срабатывания - все маски событий сбрасываются - и их надо восстанавливать снова..... :)
                                                                            Поэтому тут и пишется
                                                                            ExpandedWrap disabled
                                                                              for ( ; ; )
                                                                                  {
                                                                                  FD_ZERO(&readfds);
                                                                                  FD_ZERO(&error_set);
                                                                                  FD_SET(sock, &readfds);
                                                                                  FD_SET(sock, &error_set);

                                                                            .............
                                                                            Ну а насчет как работает....
                                                                            Так этот код не был заточен под HTTP - естественно надо видоизменять......
                                                                            Теперь ваша задача - прочувствовать код......это сетевое программирование - а не хухры мухры.... :yes:
                                                                              а еще вопрос.
                                                                              принял я эти данные, хочу продолжать принимать дальше. комментирую break
                                                                              программа сначала ждет принятия данных, каждые &tv печатает по точке, потом когда данные отосланы, принимает их, распечатывает, возвращается к select, он ей что то говорит и она пропускает чтение - начинает просто бесконечно из-за for (;;) ставить точки без всяких таймаутов. а что нужно сделать чтобы опять ждала принятия данных?
                                                                              Сообщение отредактировано: sign63 -
                                                                                селект возвращает единицу если он успешно отработал. Если селект вылетел по таймауту - он возвращает ноль. Если случилась ошибка - он возвращает отрицательный результат.
                                                                                Точка у тебя печатается не по таймауту, а по любому из трех событий - прием данных, ошибка, таймаут. Это первое.
                                                                                Чтобы оно не ставило точки - закоментируй принтф. Чтобы оно не вылетало по таймауту - передай в селект в качестве последнего аргумента ноль.
                                                                                  эмм, еще вопрос - моя готовая программка на локальном компе открывает порт, всё время разный. как можно указать собственный?
                                                                                  вот скрин http://imm.io/4nO
                                                                                    bind?
                                                                                    1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                                    0 пользователей:


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