c++ - C++ - 绑定()失败
问题描述
我正在尝试学习 C++ 中的网络,并且正在尝试设置一个简单的演示,在该演示中我在端口 5000 上打开一个 TCP 服务器,然后立即关闭它。这是我的代码:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int port = 5000;
std::cout << "Port: " << port << "\n";
int socketdesc = socket(SOCK_STREAM, AF_INET, 0);
if (socketdesc == 0)
{
std::cout << "Failed to create socket description.\n";
return 1;
}
int opt = 1;
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
std::cout << "Failed to attach socket.\n";
return 1;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(socketdesc, (struct sockaddr *)&address,
sizeof(address)) < 0)
{
std::cout << "Failed to bind socket!\n";
return 1;
}
std::cout << "Listening with protocol TCP on port" << port << ".\n";
if (listen(socketdesc, 3) < 0)
{
std::cout << "Failed to listen!\n";
return 1;
}
if (shutdown(socketdesc, SHUT_RDWR) < 0)
{
std::cout << "Failed to close socket!\n";
return 1;
}
std::cout << "TCP test succeeeded.\n";
return 0;
}
尝试将套接字绑定到端口 5000 时出现错误。设置 TCP 服务器端口出了什么问题?
PS:选择位到底是什么(我正在关注教程并同时查看 sys/socket 的文档)?
解决方案
在您到达之前,您的代码中有几个错误bind()
:
int socketdesc = socket(SOCK_STREAM, AF_INET, 0);
您有前 2 个参数值,调用需要看起来像这样:
int socketdesc = socket(AF_INET, SOCK_STREAM, 0);
如果 (socketdesc == 0)
socket()
出错时返回 -1,而不是 0。
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)))
setsockopt()
出错时也返回 -1。
但更重要的是,您不能像这样在一次调用中组合多个套接字选项。您需要setsockopt()
单独调用每个选项:
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
...
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
...
话虽如此,试试这个:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main()
{
int port = 5000;
std::cout << "Port: " << port << "\n";
int socketdesc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socketdesc == -1)
{
std::cout << "Failed to create socket descriptor. " << strerror(errno) << "\n";
return 1;
}
int opt = 1;
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
{
std::cout << "Failed to set SO_REUSEADDR option. " << strerror(errno) << "\n";
return 1;
}
if (setsockopt(socketdesc, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0)
{
std::cout << "Failed to set SO_REUSEPORT option. " << strerror(errno) << "\n";
return 1;
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(socketdesc, (struct sockaddr *)&address, sizeof(address)) < 0)
{
std::cout << "Failed to bind socket! " << strerror(errno) << "\n";
return 1;
}
std::cout << "Listening with protocol TCP on port" << port << ".\n";
if (listen(socketdesc, 3) < 0)
{
std::cout << "Failed to listen on socket! " << strerror(errno) << "\n";
return 1;
}
if (shutdown(socketdesc, SHUT_RDWR) < 0)
{
std::cout << "Failed to close socket! " << strerror(errno) << "\n";
return 1;
}
close(socketdesc);
std::cout << "TCP test succeeeded.\n";
return 0;
}
推荐阅读
- angular - 将 Angular 8 更新为 9 时在 ../node_modules/@types/jquery/index.d.ts:8143:87 中构建错误
- python - 无法为 + 解析不受支持的操作数类型:“int”和“list”
- java - 限制 Reactor 中的订阅并发
- wordpress - 客户看不到新的下载链接
- azure - 由于 grant_type 问题,无法在逻辑应用中获取 OAuth 令牌
- python - 如何像在照片中一样在 tkinter 中定位按钮?
- c - 使用 while/if 在其中切换大小写会产生错误
- react-native - React Native resizeMode:'contain'不适用于expo?
- c# - 如何使用 SpreadsheetLight 选择要在 Excel 图表中显示的系列?
- azure - 如何使用 Python 从 Azure Data Lake Storage Gen2 中的事件中心访问捕获的数据