gpt4 book ai didi

c++ - Multipe Send( )'s and Recv()' s 使用 Winsock2

转载 作者:可可西里 更新时间:2023-11-01 11:10:16 25 4
gpt4 key购买 nike

我正在使用 Winsock2 进行一个小型网络项目。我正在使用 TCP 连接,实际上我正在使用 IRC 作为示例,因为 IRC 相当简单。我正在做的是连接到服务器并发送初始缓冲区,以便服务器识别连接。这很好用。

让我担心的是我无法再次写入套接字。如果我在发送初始缓冲区后不使用 shutdown()(在 SD_SEND 上),我的程序似乎会挂起。

所以我要发送的下一个数据(基于 RFC 1459)是 USER 和 NICK 信息,但是,我觉得使用 shutdown() 是导致我当前问题的原因。有没有办法重新初始化写入套接字?

谢谢!

添加代码

请注意,这些位于一个类中,因此它仍然可能会稍微模糊。我正在使用我拥有的元素将它写成一个更简单的示例。一切都已正确定义,所以如果我忘记定义,我深表歉意,但我的许多重复变量都是为类的范围定义的。

int main(int argc,char *argv[])
{
int iResult;
SOCKET Connection;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
throw "Startup failed!";

// Prep stuff
ZeroMemory(&hints,sizeof(hints)); // This struct is defined addrinfo
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Now resolve server addr
iResult = getaddrinfo(argv[1],argv[2],&hints,&result);
if(iResult != 0)
throw "getaddrinfo() failed!";

// Now try to connect
for(ptr=result;ptr != NULL;ptr = ptr->ai_next)
{
Connection = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); // defined in that "hints" struct. argument number 2
if(Connection == INVALID_SOCKET)
{
freeaddrinfo(result);
WSACleanup();
throw "Error at socket();";
}

// Connect to server
iResult = connect(Connection, ptr->ai_addr, (int)ptr->ai_addrlen);
if(iResult != 0)
{
closesocket(Connection);
Connection = INVALID_SOCKET;
continue;
}
break;
}

freeaddrinfo(result);

// Send initial buffer so server know you're there :)
iResult = send(Connection, "", 1, 0);
if(iResult == SOCKET_ERROR)
{
close();
throw "Could not send initial buffer!";
}

// Close this connection for the inital buffer
iResult = shutdown(Connection, SD_SEND);
if(iResult == SOCKET_ERROR)
{
close();
throw "Could not close initial buffer socket!";
}

bool connected = true;

// This is taken from my read function within the class
// BEGIN READ FUNCTION
iResult = 0; // Reset
std::string data = ""; // Capture the output and send it all at once!

// This only works if we're connected sweet cakes <3
if(connected)
{
do
{
iResult = recv(socket, recvbuf, BUFLEN, 0);
if(iResult > 0)
{
// Working properly
// Save all data even if there is more than BUFLEN sent
continue;
}
else if(iResult == 0)
// Connection closed properly
break;
else
printf("ERROR!");
} while(iResult > 0);
}
data += recvbuf;
ZeroMemory(&recvbuf,sizeof(recvbuf));
// Function returns std::string but essentially this is what happens
printf("%s",data.c_str());
// END READ FUNCTION

// BEGIN WRITE FUNCTION
iResult = 0; // Reset
SOCKET socket = Connection; // Write function arg 1
char *data; // Write function arg 2

iResult = send(socket,data,(int)strlen(data),0);
if(iResult == SOCKET_ERROR)
{
close();
printf("Could not write data: %ld",WSAGetLastError());
return 1;
}

// Data sent, let's close the write socket
iResult = shutdown(socket, SD_SEND);
if(iResult != 0)
{
close();
printf("Could not close write socket!");
return 1;
}

//return iResult;
// END WRITE FUNCTION

// Now that will produce "Could not write data: 0" for any value of data
// So realistically I want to send the USER and NICK data, then read
// and probably process a PING string from the server and send my PONG response

return 0;
}

我希望这能澄清事情!

编辑

我想我已经弄清楚出了什么问题。我对我的代码进行了下面列出的更正;谢谢你们。但是,这是我的读取循环弄乱了事情。即使在它拥有所有信息之后,它似乎也在等待连接关闭,然后再发送输出。有任何想法吗?我的输出目前看起来像这样(写入的字节数/总字节数是我添加的内容,以确保一切正常)

Bytes Written: 41
Bytes Total: 41
Data: ERROR :Closing Link: raged123[127.0.0.1] 6667 (Ping timeout)
...
:irc.foonet.com NOTICE AUTH :*** Found your hostname (cached)
PING :2ED39CE5
[A bunch of funny characters]WinSock 2.0

所以它似乎已经超时,因为 PING 没有及时收到 PONG,但是,我不能在没有先处理 PING 请求的情况下发送 PONG,这意味着我需要能够在连接关闭之前读取输出.有什么想法吗?

最佳答案

我可以推荐一个关于这个主题的有趣文档吗? Beej's Guide to Network Programming 的第 6 章和第 7 章

它有几个例子。

关于c++ - Multipe Send( )'s and Recv()' s 使用 Winsock2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3322538/

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