Я новичок в программировании на С ++, и я немного исследовал зависание приложения при отправке данных через программирование сокетов, так как всякий раз, когда происходит изменение между основным и дополнительным серверами при создании и подключении к сокету, я использую код ниже и я видел, что иногда это занимает больше времени или зависает в SELECT местоположении. Код как ниже. И могу ли я знать, когда я использую статический класс и использую его из разных классов для отправки данных, будет ли проблема безопасности потока. Т.е. потеря данных? Неужели весь приведенный ниже код необходим просто для создания и подключения к сокету?
USES_CONVERSION;
SOCKADDR_IN ServerAddr;
// Initialize ServerAddr
memset(&ServerAddr,0,sizeof(ServerAddr));
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = inet_addr(ipAddress);
ServerAddr.sin_port = htons((u_short)portNo);
// Create SocketPrimary
SocketPrimary = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (SocketPrimary == INVALID_SOCKET)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - WSASocket(TCP) call with error %ld"), WSAGetLastError());
return false;
}
// Set timeout option
if (setsockopt(SocketPrimary, SOL_SOCKET, SO_RCVTIMEO, (char *)&RecieveTimeOut, sizeof(RecieveTimeOut)) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a setsockopt for SO_RCVTIMEO call with error %ld"), WSAGetLastError());
Close(SocketPrimary,TRUE);
return false;
}
// Set timeout option
if (setsockopt(SocketPrimary, SOL_SOCKET, SO_SNDTIMEO, (char *)&SendTimeOut, sizeof(SendTimeOut)) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a setsockopt for SO_SNDTIMEO call with error %ld"), WSAGetLastError());
Close(SocketPrimary,TRUE);
return false;
}
// Set connect portno on address
if (WSAHtons(SocketPrimary, (u_short)portNo, &(ServerAddr.sin_port)) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a WSAHtons call with error %ld"), WSAGetLastError());
Close(SocketPrimary,TRUE);
return false;
}
// Set non-blocking
DWORD BlockMode = 1;
if (ioctlsocket(SocketPrimary, FIONBIO, &BlockMode) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a ioctlsocket (non-blocking) call with error %ld"), WSAGetLastError());
Close(SocketPrimary,TRUE);
return false;
}
// Connect socket
if (WSAConnect(SocketPrimary, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr), NULL, NULL, NULL, NULL) == SOCKET_ERROR)
{
int ConnectError = WSAGetLastError();
if (ConnectError != WSAEWOULDBLOCK)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T("Primary server connection failed - to connect to server with error %ld"), ConnectError);
Close(SocketPrimary,TRUE);
return false;
}
}
// Wait for connect (use select as the socket is non-blocking at this time)
fd_set ConnectSockets;
ConnectSockets.fd_count = 1;
ConnectSockets.fd_array[0] = SocketPrimary;
TIMEVAL Timeout;
Timeout.tv_sec = ConnectTimeOut / 1000;
Timeout.tv_usec = (ConnectTimeOut % 1000) * 1000;
if (select(0, NULL, &ConnectSockets, NULL, &Timeout) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a select call with error %ld"), WSAGetLastError());
Close(SocketPrimary, TRUE);
return false;
}
else
{
if (ConnectSockets.fd_count == 0)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - timedout to connect..."));
Close(SocketPrimary, TRUE);
return false;
}
}
// Set blocking
BlockMode = 0;
if (ioctlsocket(SocketPrimary, FIONBIO, &BlockMode) == SOCKET_ERROR)
{
LogToEventLog(EVENTLOG_WARNING_TYPE, EVENTID_WINSOCK_ERROR, _T(" Primary server connection failed - a ioctlsocket (blocking) call with error %ld"), WSAGetLastError());
Close(SocketPrimary, TRUE);
return false;
}
LogToEventLog(EVENTLOG_INFORMATION_TYPE, 0, _T(" connected to primary server with local socket id %ld"), SocketPrimary);
// Return
return true;