TCP-соединение не установлено в Windows - C ++ - PullRequest
0 голосов
/ 18 мая 2019

Использование windows 10, visual studio 2017.

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

bool IPTunnel::runBlock(void)
{
   int ready = inputSignals[0]->ready(); //int ready2 = inputTCPConnetion[0]->ready();
WSADATA wsaData;

   int iResult;

   iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
   if (iResult != 0) {
       printf("WSAStartup failed: %d\n", iResult);
       return 1;
   }

   //server
   SOCKET sockfd, newsockfd;
   int portno;
   socklen_t clilen;
   char buffer[256];
   struct sockaddr_in serv_addr, cli_addr;
   int n;

   char sendbuf[15] = "this is a test";
   char recvbuf[256];
   int resul;




   // create a socket(int domain, int type, int protocol)
   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0)
       printf("\n ERROR opening socket");

   // clear address structure
   bzero((char *)&serv_addr, sizeof(serv_addr));

   portno = 5500;

   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;//inet_addr("127.0.0.1");
   serv_addr.sin_port = htons(portno);

   //if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
   bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
   //   printf("\n ERROR on binding");

   listen(sockfd, 5);

   clilen = sizeof(cli_addr);


   newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
   if (newsockfd < 0)
       printf("ERROR on accept");

   printf("server: got connection from %s port %d\n",inet_ntop(serv_addr.sin_family,
       &serv_addr.sin_addr.s_addr, buffer, clilen), portno);

   //client
   int socketId = socket(PF_INET, SOCK_STREAM, 0);
   struct sockaddr_in serverAddr;
   socklen_t addrSize = sizeof(serverAddr);
   bzero((char*)&serverAddr, sizeof(serverAddr));
   serverAddr.sin_family = AF_INET;
   serverAddr.sin_port = htons(8080);
   serverAddr.sin_addr.s_addr = INADDR_ANY;
   connect(socketId, (struct sockaddr*)&serverAddr, addrSize);

   resul = send(socketId, sendbuf, (int)strlen(sendbuf), 0);
   if (resul == SOCKET_ERROR) {
       printf("send failed: %d\n", WSAGetLastError());
       closesocket(newsockfd);
       WSACleanup();
       return 1;
   }
   printf("Bytes Sent: %ld\n", resul);

   do{
       resul = recv(newsockfd, recvbuf, 256, 0);
       if (resul > 0)
           printf("Bytes received: %d\n", resul);
       else if (resul == 0)
           printf("Connection closed\n");
       else
           printf("recv failed: %d\n", WSAGetLastError());
   } while (resul > 0);


   bzero(buffer, 256);


   resul = recv(socketId, buffer, 256, 0);

   fprintf(stdout, "%s %s\n", "Response from server", resul);

   while (true) { Sleep(1000); }
   return 0;
}

Это вывод:

сервер: получено соединение с порта 0.0.0.0 5500

Ошибка подключения: 10038

(я проверил эту ошибку 10038 https://docs.microsoft.com/en-us/windows/desktop/winsock/windows-sockets-error-codes-2)

Что я делаю не так? Заранее спасибо.

1 Ответ

1 голос
/ 18 мая 2019
resul = send(socketId, sendbuf, (int)strlen(sendbuf), 0);

Использование strlen в send - плохая идея, вы уверены, что ваша строка завершена нулем, и вы не хотите, чтобы нули отправлялись?

int socketId = socket(PF_INET, SOCK_STREAM, 0);

Должно быть SOCKET, а не int.

connect(socketId, (struct sockaddr*)&serverAddr, addrSize);

вы проверяли возвращаемое значение? Подключение к порту 8080 при прослушивании другого порта?

Попробуйте вместо этого использовать WSAConnectByName , намного проще, чем заполнение sockaddrs, совместимых с IPv6.

Кроме того, вам нужны темы. Сервер должен вызвать accept (), и это заблокирует. recv () / send () являются блокирующими функциями.

...