I'm using VC++ on Visual Studio 2010.
Now I've got some problem. I think it's so silly question but I want to get a clear answer.
How can I get CLOSE_WAIT
state of an selected SOCKET
?
// SocketThreadConn.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <WinSock.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
#define PR_RECORED_TIME 10*1000 // (ms)
BYTE* pByteCamData = NULL;
INT nHeight = 900;
INT nWidth = 1600;
INT nSpect = 3;
INT nSolution = nHeight * nWidth * nSpect;
VOID SendRecoredData(SOCKET socket2operation);
int _tmain(int argc, _TCHAR* argv[])
{
pByteCamData = new BYTE[nSolution]; // <-- use [], not ()!
//----------------------
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
delete[] pByteCamData;
return 1;
}
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
SOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service = {};
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");
service.sin_port = htons(27015);
if (bind(ListenSocket, (SOCKADDR *) &service, sizeof(service)) == SOCKET_ERROR) {
wprintf(L"bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// Listen for incoming connection requests.
// on the created socket
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
wprintf(L"listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
//----------------------
// Accept the connection.
wprintf(L"Waiting for client to connect...\n");
SOCKET AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 1;
}
wprintf(L"Client connected.\n");
SendRecoredData(AcceptSocket); // <-- logic fix!
// No longer need client socket
closesocket(AcceptSocket); // <-- CLOSE_WAIT fix!
// No longer need server socket
closesocket(ListenSocket);
WSACleanup();
delete[] pByteCamData;
return 0;
}
VOID SendRecoredData(SOCKET socket2operation)
{
if(IsSocketAlive(socket2operation) == 0)
return;
INT nCountDown = 5;
INT nSentData, nNumToSend;
BYTE *pData;
do
{
if (nCountDown == 0)
{
nCountDown = 5;
pData = pByteCamData;
nNumToSend = nSolution;
while (nNumToSend > 0) <-- send() fix!
{
nSentData = send(socket2operation, (char*)pData, nNumToSend, 0);
if (SOCKET_ERROR == nSentData) {
wprintf(L"send failed with error: %d\n", WSAGetLastError());
return;
}
pData += nSentData;
nNumToSend -= nSentData;
}
wprintf(L"Sent Camera Data OK [%d] Bytes\n", nSolution);
}
Sleep(PR_RECORED_TIME);
--nCountDown;
}
while (TRUE);
}
INT IsSocketAlive(SOCKET socket2check)
{
if (socket2check == INVALID_SOCKET)
return FALSE;
INT nError_code = -1;
INT nError_code_size = sizeof(nError_code);
INT nRetValue = getsockopt(socket2check, SOL_SOCKET, SO_ERROR, (CHAR*)&nError_code, &nError_code_size);
// if (nRetValue != -1)
{
// _tprintf(_T("Error getting socket error code : %d \n"), strerror(nRetValue));
}
if (nError_code != 0)
{
_tprintf(_T("Socket error : %d \n"), strerror(nError_code));
}
switch (nError_code)
{
case 0:
return TRUE;
break;
case SOCKET_ERROR:
return FALSE;
default:
return FALSE;
}
}
A problem is CLOSE_WAIT
'ed' socket is checked as alive socket.
When SocketThreadConn.exe
is working on while loop
, it doesn't break loop
though Listen socket is CLOSE_WAIT
.
How can I check accepted socket is ESTABLISHED
?
(This code has changed by @Remy Lebeau)
How can I check is a socket is still ESTABLISHED
not using send()
or GetTcpTable()
.
Function GetTcpTable()
is working well but I have to find socket only using their value(USHORT). There is no field for socket value in MIB_TCPTABLE
.