gpt4 book ai didi

C++ 网络,recv() 无缘无故失败(?)

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

我正在用 C++ 编写聊天服务器以供自己娱乐,但总体而言,我对网络还很陌生。我的知识来自 Beej 的指南,this site ,以及 Kurose&Ross 的自上而下方法。

我的问题是,我编写的代码非常类似于您可以在链接中找到的代码,但它不起作用。当我尝试在服务器上使用 recv() 函数时程序失败。

我知道 recv() 可以返回任意数量的字节,但它只给了我 -1。我知道我需要一个循环来拼凑正在发送的消息,但目前还没有类似的东西。然而,客户端中的 send() 表示它发送了缓冲区中指定的数量(是的,我知道这可能有点矫枉过正,但不确定这是否是一个错误)。

对我来说,服务器好像……以某种方式关闭了?我很确定我在某个地方搞砸了,有一行代码我真的不确定(寻找评论)。我昨天设法让它工作,但之后出了点问题。

我对套接字编程和一般的任何类型的网络真的很陌生,但是函数调用和诸如此类的东西来自指南,我有预感问题将出在我指定端口和地址的部分,也许是字节没有到达服务器,因为我将它们发送到其他地方?但是,如果 accept() 有效,这是否意味着形成了 TCP 连接,之后我就不能使用它了吗?

我正在使用最新版本的 Lubuntu linux,如果有帮助的话。

如果你发现了问题,能告诉我如何正确地做吗?无论如何,这是服务器的代码:

void start() {

char message[1024] = "";

int socketfd = socket( AF_INET, SOCK_STREAM, 0 ), opt = 1, new_socket;

struct sockaddr_in address;
struct sockaddr_storage cl_addr;
socklen_t len = sizeof(address);

if( socketfd != 0 ) {

address.sin_family = AF_INET;
address.sin_port = htons( PORT );
address.sin_addr.s_addr = INADDR_ANY;

if( setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(int)) < 0 ) {
perror("Setsockopt failed");
exit(EXIT_FAILURE);
}

if( bind( socketfd, (struct sockaddr*)&address, len ) < 0 ) {
perror("Couldn't bind to port");
exit(EXIT_FAILURE);
}

if( listen( socketfd, 3 ) < 0 ) {
perror("Listening on port failed");
exit(EXIT_FAILURE);
}

if( (new_socket = accept( socketfd, (struct sockaddr *)&cl_addr, (socklen_t*)&len ) < 0) ) {
perror("Couldn't accept request");
exit(EXIT_FAILURE);
}

/// This is where it fails
std::cout << recv( new_socket, message, 1024, 0) << std::endl;
close(new_socket);
}
else {
perror("Couldn't open socket");
exit(EXIT_FAILURE);
}
close( socketfd );
}

现在客户端:

int main(void) {

int sockfd;

struct sockaddr_in serv_addr;
char hello[1024] = "Hello";

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);

/// I'm not sure about this !!
inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if( sockfd == 0 ) {
perror("Opening socket failed");
exit(EXIT_FAILURE);
}

if( connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) != -1 ) {
/// Says it sent 1024, but sever doesn't recieve it, what gives ?
int test = send( sockfd, hello, sizeof(hello), 0);
std::cout << test << std::endl;
}
else {
perror("Error");
exit(EXIT_FAILURE);
}

如您所见,它类似于链接中的代码。服务器代码只是一个功能,还有其他部分代码,比如创建用户文件,但没有一个在网络部分使用,所以我不想再白发 800 行代码。服务器的 main() 只是我创建一个服务器类的对象并在其上调用 start()。

我想尽我所能进行改进,所以如果您发现我可以做得更好的地方,请告诉我,无论是通用编码风格还是其他方面。另外,这是我在这里的第一个问题,我的第一语言不是英语,请对我放轻松 :)

最佳答案

这是一个括号问题。

这一行:

if( (new_socket = accept( socketfd, (struct sockaddr *)&cl_addr, (socklen_t*)&len  ) < 0) ) {

<运算符的评估优先级高于 =运营商。

new_socket正在分配 accept() < 0 的评估,这是一个错误的表达,所以 new_socket被分配零。

这可能是你的意思:

if (new_socket = accept( socketfd, (struct sockaddr *)&cl_addr, (socklen_t*)&len ) < 0)

但这不太容易出错:

new_socket = accept( socketfd, (struct sockaddr *)&cl_addr, (socklen_t*)&len  ); 
if (new_socket < 0) {
perror("Couldn't accept request");
exit(EXIT_FAILURE);
}

关于C++ 网络,recv() 无缘无故失败(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52026363/

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