gpt4 book ai didi

c++ - 套接字服务器以缓冲区大小接收数据

转载 作者:行者123 更新时间:2023-12-01 14:52:19 24 4
gpt4 key购买 nike

我一个接一个地发送不同大小的数据包,如何以我发送的大小分别接收数据包,而不是在缓冲区中累积。似乎现在服务器添加到缓冲区直到它填满它然后我可以处理它们。

例子:

Buffer size: 84.

Send from client: 84 bytes, 76 bytes, 76 bytes, 80 bytes

Receive in server: 84 bytes, 84 bytes, 84 bytes, 64 bytes.



我想在发送它们时收到它们。是否可以?
    int port = stoi(getConfig("server_port"));
std::string ipAddress = getConfig("ip_address");

// Create a socket
int listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening < 0){
std::cerr << "Can't create a socket!" << endl;
Logger("Can't create a socket!");
exit(-1);
}
std::cout << "The socket server was created successfully." << endl;

// Bind the socket to a IP / port
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);

if (bind(listening, (sockaddr*)&hint, sizeof(hint)) < 0){
cerr << "Can't bind to IP/port!" << endl;
Logger("Can't bind to IP/port!");
exit(-1);
}

// Mark the socket for listening in
if (listen(listening, SOMAXCONN) < 0){
cerr << "Can't listen!" << endl;
Logger("Can't listen!");
exit(-1);
}

// Accept a call
sockaddr_in client;
socklen_t clientSize = sizeof(client);
char host[NI_MAXHOST];
char svc[NI_MAXSERV];

while(true){
int clientSoket = accept(listening, (sockaddr*)&client, &clientSize);
if(clientSoket < 0){
cerr << "Problem with client connecting!" << endl;
Logger("Problem with client connecting!");
break;
}
cout << "The client whas conected successfully." << endl;

memset(host, 0, NI_MAXHOST);
memset(svc, 0, NI_MAXSERV);

int result = getnameinfo((sockaddr*)&client, clientSize, host, NI_MAXHOST, svc, NI_MAXSERV, 0);
if(result == 0) {
cout << host << " connected on " << svc << endl;
} else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on " << ntohs(client.sin_port) << endl;
}

// While receiving
char buff[84];
while(true){
// Clear the buffer
memset(buff, 0, sizeof(buff));

// Wait for a message
int bytesRecv = recv(clientSoket, buff, sizeof(buff), 0);
if(bytesRecv < 0){
cerr << "There was a connection issue!" << endl;
Logger("There was a connection issue!");
break;
}

if(bytesRecv == 0){
cout << "The client disconnected." << endl;
Logger("The client disconnected");
break;
}

cout << "bytesRecv: " << bytesRecv << endl;
}

// Close the socket
close(clientSoket);
}

最佳答案

不,流套接字不能那样工作。

流套接字是一个非结构化的字节流,无论如何都没有任何结构。在这方面,它与普通文件没有什么不同。如果您将不同大小的记录写入一个普通文件,并且现在准备读回它们,您希望如何读取可变大小的记录?

无论您在此处给出哪个答案,相同的答案都适用于套接字,另外还有一个 read() on a socket 不保证你会读多少,除了它会小于或等于 size read() 的参数.这是您从 read() 获得的唯一保修。 .

如果发件人调用write()两次(顺便说一下,套接字也不能保证无论你想写多少 write ,写多少,write 也可以返回小于或等于其 size 参数的字节数,并且由您的代码决定如何处理它),一次写入 76 个字节,第二次写入 84 个字节,read()在初始读取时(假设缓冲区大小足够大)可以读取 1 到 160 字节之间的任意字节数。

如果您希望实现某种正式的结构、某种记录,则由您自己决定如何在这些约束条件下实现它。也许通过发送每条记录的大小(以字节为单位),然后是记录本身。或者做任何你想做的事。请记住,您没有任何保证,无论如何,个人 read()返回。例如,如果您首先发送记录计数,作为四字节值。您的初始 read()可能返回一个、两个或三个字节。您的代码必须准备好处理任何不测事件。

关于c++ - 套接字服务器以缓冲区大小接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62386920/

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