c++ - 清除缓冲区-Winsock

标签 c++ sockets client buffer winsock

这是我在 Windows 中使用 winsock 用 C++ 编写的客户端程序的代码。

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include<sstream>
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512
#pragma comment(lib,"WS2_32.lib");

struct addrinfo *result = NULL,
         *ptr = NULL,
         hints;

int main()
{
WSAData wsadata;
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "1,2,3,4!!";
char recvbuf[512];



iResult=WSAStartup(MAKEWORD(2,2),&wsadata);
if(iResult!=0)
{
    std::cout<<"WSAStartup failed"<<iResult<<std::endl;
    getchar();
    return 1;
}

ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

char arr[20]="localhost";

iResult = getaddrinfo(arr, DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
    std::cout<<"getaddrinfo failed: "<<iResult;
    getchar();
    WSACleanup();
    return 1;
}

SOCKET ConnectSocket = INVALID_SOCKET;
ptr=result;
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
ptr->ai_protocol);

if (ConnectSocket == INVALID_SOCKET)
{
    std::cout<<"Error at socket(): "<<WSAGetLastError();
    getchar();
    freeaddrinfo(result);
    WSACleanup();
    return 1;
}

iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
    closesocket(ConnectSocket);
    ConnectSocket = INVALID_SOCKET;
}

freeaddrinfo(result);

if (ConnectSocket == INVALID_SOCKET) 
{
    std::cout<<"Unable to connect to server!"<<std::endl;
    getchar();
    WSACleanup();
    return 1;
}



for(;;)
{
int i=15;
int x=12;
int z=1;
iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
std::cout<<"Recieved data: "<<recvbuf<<std::endl;
}

iResult = shutdown(ConnectSocket, SD_SEND);

if (iResult == SOCKET_ERROR) 
{
    std::cout<<"shutdown failed: "<<WSAGetLastError();
    getchar();
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

if (iResult == 0)
    std::cout<<"Connection closed\n";
else
    std::cout<<"recv of client failed: "<<WSAGetLastError();

iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) 
{
    std::cout<<"shutdown failed: "<<WSAGetLastError();
    closesocket(ConnectSocket);
    WSACleanup();
    return 1;
}

closesocket(ConnectSocket);
WSACleanup();
getchar();
return 0;
}

我收到的信息很好。唯一的问题是每次收到一些数据时我都想清除缓冲区。 如果我发送 a、b、c、d,当前代码的输出类似于

a,b,c,d

aa,bb,cc,dd

aaa,bbb,ccc,ddd

虽然我希望我的输出是 a、b、c、d,因为它不断接收此信息。如何做到这一点?

最佳答案

您提供的这段代码看起来像一个无限循环:

for(;;)
{
int i=15;
int x=12;
int z=1;
iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
std::cout<<"Recieved data: "<<recvbuf<<std::endl;
}

最重要的是,它输出 recvbuf 就像它是一个字符串一样,但不能保证它会被 \0 终止,并且可能会导致如果您实际读取完整的 DEFAULT_BUFLEN 字节数据,则会出现未定义的行为。我建议在打印前进行 string 转换。但在此之前,应该检查recv 的返回值。

iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
if (iResult <= 0) break;
std::cout<<"Received data: " <<std::string(recvbuf,iResult)<<std::endl;

关于c++ - 清除缓冲区-Winsock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11662625/

相关文章:

python - 为什么我的 python 套接字无法连接到另一台计算机?

client - NFS 客户端库

javascript - gjs 如何使用 g_data_input_stream_read_line_async 在 Gnome Shell 扩展中读取套接字流

c++ - 字符串复制到字符数组

c++ - 为什么win32线程不自动退出?

c++ - 如何将 DWORD 颜色变量提取到其参数中? (十进制类型)

Java 隧道 HTTPS(SSL) 请求

linux - net.unix.max_dgram_qlen 问题

http - WifiClient 未连接到 XAMPP 服务器

c++ - extern "C"声明如何工作?