Получаю ошибочное соединение Socket-ов под Windows 7
От: MDenis2k  
Дата: 26.07.10 07:07
Оценка:
В тесте ниже получаю ошибочное присоединение сокетов на TCP порты 50020 ... 50029, при условии, что никто эти порты не открывает на прослушивание. Ошибку получаю только под Windows 7. В течении суток работы теста все сокеты будут присоединены. Тестировал на чистой Windows 7 под VMWare. TCPView (SysInternals) говорит, что соединение произведено на удалённый адрес "localhost" 50020... 50029 (процесса который бы их слушал в списке нет). Поискал в Интернете — никто о такой проблеме не пишет.

Минимальный тест (см. ниже) создавал как консольный проект под C++ Builder 2007, собирал как MultyThread, C++. Тестовая OS: чистая Windows 7 32 разряда (NT 6.1 7600 Enterprise). Пробовал также собирать под MSVC Studio 2005 — результат тот же.

Что-то делаю не так? Возможно это уже известная проблема? Заранее спасибо.

Листинг:

//---------------------------------------------------------------------------
#include <windows.h> // MessageBox
#include <process.h> // beginThreadEx
#include <stdio.h>   // printf
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma link "ws2_32.lib"
//---------------------------------------------------------------------------
#pragma argsused
//---------------------------------------------------------------------------

// Декларации:
void showInfo(char* apInfo);
void logOut(char* apInfo);

unsigned __stdcall threadFunc(void* apThread);
int tryConnect(int anPortNum);
//---------------------------------------------------------------------------



int main(int argc, char* argv[])

  WSADATA wsaData;

  int nResult = -1;
  nResult = ::WSAStartup(MAKEWORD(2, 0), &wsaData);
  if(nResult)
  {
    showInfo("Ошибка WSAStartup()");
  }
  else
  {
    showInfo("WSA Started");
  }


  // Создадим 10 нитей:
  HANDLE hThread = NULL;
  unsigned int uiThreadID = 0;
  int* pnPort = NULL;
  for(int i=0; i<10; i++)
  {

    // Будут лики, но это сейчас не важно
    pnPort = new int;
    if(pnPort)
    {
      // Порты, куда коннектимся с 50020 до 50029
      *pnPort = 50020 + i;
    }

    hThread = (HANDLE)_beginthreadex(
      NULL,
      1024*1024,
      &threadFunc,
      (void*)pnPort,
      0,
      &uiThreadID);
    if(hThread == INVALID_HANDLE_VALUE)
    {
      showInfo("Ошибка создания нити");
      continue;
    }
  }

  // Рисовать нормальное завершение нитей не охото. По Ctrl+C если что можно убить.
  for(;;)
  {
    ::Sleep(INFINITE);
  }

  return 0;

//---------------------------------------------------------------------------


unsigned __stdcall threadFunc(
  void* apThread)

  for(;;)
  {
    tryConnect(*((int*)apThread));

    ::Sleep(1000);
  }
};
//---------------------------------------------------------------------------

int tryConnect(
  int anPortNum)


  // Готовим структуру:
  struct sockaddr_in sockaddr;
  ::ZeroMemory(&sockaddr, sizeof(sockaddr));

  sockaddr.sin_family = AF_INET;
  sockaddr.sin_addr.S_un.S_addr = ADDR_ANY;


  {
    const char* szHostName = "localhost";
    ULONG ulIP = ADDR_ANY;

    // тогда по буквам но это медленнее
    struct hostent* pbuf_host = NULL;
    pbuf_host = ::gethostbyname(szHostName);
    if(!pbuf_host)
    {
      showInfo("pbuf_host is NULL");
      return -1;
    }

    ulIP = *((ULONG*)pbuf_host->h_addr_list[0]);

    sockaddr.sin_addr.S_un.S_addr = ulIP;
  }

  {
    sockaddr.sin_port = ::htons(anPortNum);
  }


  SOCKET sSocket = INVALID_SOCKET;
  sSocket = ::WSASocket(
    AF_INET,
    SOCK_STREAM,
    IPPROTO_TCP,
    NULL,
    0,
    WSA_FLAG_OVERLAPPED);
  if(sSocket == INVALID_SOCKET)
  {
    DWORD dwErrcode = WSAGetLastError();
    showInfo("Ошибка создания сокета");

    return -3;
  }


  // Пытаемся присоединится:
  int nResult = -1;
  nResult = ::connect(
    sSocket,
    (const struct sockaddr*)&sockaddr,
    sizeof(sockaddr));
  if(nResult)
  {
    DWORD dwErrcode = WSAGetLastError();

    // Выводить не буду - это норма
    //showInfo("Ошибка коннекта");
    logOut("Error connecting");

    ::closesocket(sSocket);

    return -5;
  }
  else
  {
    //AnsiString strInfo = "Соединение установлено! Порт: " + IntToStr(anPortNum);
    char szInfo[128];
    sprintf(szInfo, "Соединение установлено! Порт: %d", anPortNum);
    showInfo(szInfo);

    ::closesocket(sSocket);
  }

  return 0;
};
//---------------------------------------------------------------------------


void showInfo(char* apInfo)

  logOut(apInfo);
  ::MessageBox(NULL, apInfo, "Информация", MB_OK);
};
//---------------------------------------------------------------------------

void logOut(char* apInfo)

  SYSTEMTIME sysTime;
  ::GetSystemTime(&sysTime);

  printf("%d:%d:%d.%d %s \r\n",
    sysTime.wHour,
    sysTime.wMinute,
    sysTime.wSecond,
    sysTime.wMilliseconds,
    apInfo);
};
//---------------------------------------------------------------------------
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.