gpt4 book ai didi

c++ - 如何获得规范套接字的 "CLOSE_WAIT"状态

转载 作者:行者123 更新时间:2023-11-30 02:22:16 24 4
gpt4 key购买 nike

我在 Visual Studio 2010 上使用 VC++。
现在我遇到了一些问题。我认为这是一个愚蠢的问题,但我想得到一个明确的答案。

如何获得所选 SOCKETCLOSE_WAIT 状态?

// 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;
}
}

问题是 CLOSE_WAIT 'ed' 套接字被检查为事件套接字。
SocketThreadConn.exe 正在处理 while 循环 时,它不会中断循环 尽管 Listen socket 是 CLOSE_WAIT

如何检查接受的套接字是否ESTABLISHED

(此代码已被@Remy Lebeau 更改)

我如何检查套接字是否仍然是 ESTABLISHED,而不是使用 send()GetTcpTable()

函数 GetTcpTable() 运行良好,但我必须仅使用它们的值 (USHORT) 来查找套接字。 MIB_TCPTABLE 中没有套接字值字段。

最佳答案

#define SOCKET_ALIVE 10
#define SOCKET_DEAD 9

INT CheckSocketAlive(SOCKET socket2check)
{
fd_set fdR;
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
FD_ZERO(&fdR);
FD_SET(socket2check, &fdR);
switch (select(socket2check + 1, &fdR, NULL,NULL, &timeout))
{
case SOCKET_ERROR:
_tprintf(_T("\tError condition. Code : [%d]\n"), WSAGetLastError());
return SOCKET_DEAD;
case 0:
return SOCKET_ALIVE;
default:
if ( FD_ISSET(socket2check, &fdR) )
{
_tprintf(_T("A read event has occurred on socket [socket2check].\n"));
return SOCKET_DEAD;
}
break;
}
}

您可以使用此函数获取所选套接字的状态。
但只有 SOCKET_ERRORSOCKET_ALIVE
您可以根据需要更改 timeout.tv_sec (1sec)

关于c++ - 如何获得规范套接字的 "CLOSE_WAIT"状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47397064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com