在man pages和程序员单证套接字选项SO_REUSEADDR,并SO_REUSEPORT针对不同的操作系统,不同的,往往非常混乱.有些操作系统甚至没有选项SO_REUSEPORT.WEB中充满了关于此主题的矛盾信息,并且通常您可以找到仅对特定操作系统的一个套接字实现的信息,这些信息甚至可能在文本中没有明确提及.
那究竟有什么SO_REUSEADDR不同SO_REUSEPORT呢?
系统是否没有SO_REUSEPORT更多限制?
如果我在不同的操作系统上使用任何一个,那么预期的行为究竟是什么?
我使用socket在linux中创建了一个聊天客户端,我希望完全破坏连接.以下是代码的相关部分:
int sock, connected, bytes_recieved , true = 1, pid;
char send_data [1024] , recv_data[1024];
struct sockaddr_in server_addr,client_addr;
int sin_size;
label:
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Socket");
exit(1);
}
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1)
{
perror("Setsockopt");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(3128);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))== -1)
{
perror("Unable to bind");
exit(1);
}
if (listen(sock, 5) == -1)
{
perror("Listen");
exit(1);
}
printf("\nTCPServer Waiting for client on port …Run Code Online (Sandbox Code Playgroud) 我知道TIME_WAIT是TCP/IP的一个组成部分,但是在SO(和其他地方)有很多问题,每秒创建多个套接字,服务器最终耗尽短暂的端口.
我发现的是,当使用TCPClient(或者Socket就此而言)时,如果我调用了Close()或者Dispose()方法,则套接字的TCP状态变为TIME_WAIT并且将在完全关闭之前考虑超时时间.
但是,如果只是将变量设置null为套接字将在下一次GC运行时完全关闭,这当然可以强制执行,而不会经历TIME_WAIT状态.
这对我来说没有多大意义,因为这是一个IDisposable对象不应该GC也调用Dispose()对象的方法?
这是一些PowerShell代码,演示了(在这台机器上没有安装VS).我使用Sysinternals的TCPView实时检查套接字状态:
$sockets = @()
0..100 | % {
$sockets += New-Object System.Net.Sockets.TcpClient
$sockets[$_].Connect('localhost', 80)
}
Start-Sleep -Seconds 10
$sockets = $null
[GC]::Collect()
Run Code Online (Sandbox Code Playgroud)
使用此方法,套接字永远不会进入TIME_WAIT状态.同样的,如果我只是手动调用之前关闭该应用程序Close()或Dispose()
有人可以解释一下是否这是一个好习惯(我想人们会说这不是).
编辑
GC已经回答了这个问题,但我仍然有兴趣找出为什么这会对套接字状态产生任何影响,因为这应该由操作系统控制,而不是.NET.
还有兴趣了解使用此方法来防止TIME_WAIT状态并最终是否是某个地方的错误(即,所有套接字是否应该通过TIME_WAIT状态?)是否是一个好习惯?
我有一个启用了JMX监控的Java应用程序,如下所示:
-Dcom.sun.management.jmxremote.port=9999 \
// some other properties omitted
Run Code Online (Sandbox Code Playgroud)
但是当我尝试重新启动应用程序时,有时我收到错误说JMX端口号已经在使用中.这是不可接受的.
所以我想为底层套接字设置SO_REUSEADDR为true以避免此错误,但没有找到相关的JMX属性.
任何的想法?
我有一个boost :: asio的服务器工作正常,除了我正在尝试添加一个检查,没有其他任何接受同一端口上的连接.如果我创建了两个服务器,其中一个始终接受连接,但另一个不报告任何错误(两个中的哪一个接受所有连接似乎是随机的).
服务器类的相关位(它是使用具有Accepted()和typedef的基类的模板,用于创建连接类型):
MessageServer ( boost::asio::io_service &io, unsigned short port_num )
: BaseServerType ( io ), acceptor_ ( io, boost::asio::ip::tcp::endpoint ( boost::asio::ip::tcp::v4(), port_num ) ) {
Listen();
}
void Listen () {
boost::system::error_code ec;
acceptor_.listen ( boost::asio::socket_base::max_connections, ec );
if ( !ec ) {
start_accept();
} else {
// not reached even if a separate process
// is already listening to that port
connection_pointer new_connection;
BaseServerType::Accepted ( new_connection );
}
}
private:
void start_accept() {
connection_pointer new_connection ( CreateConnection …Run Code Online (Sandbox Code Playgroud) 我没有看到任何重要的TCP/IP服务器不使用SO_REUSEADDR:
是否有任何用例在TCP/IP服务器上不使用SO_REUSEADDR?
我的意思是,是否会让操作系统始终使用SO_REUSEADDR来破坏任何不使用它的服务器?
你知道一个不使用SO_REUSEADDR的TCP/IP服务器吗?
(当然你可能不想在MSWindows上使用它,因为它允许在同一个端口上运行两个服务器)
我可以socat像这样使用端口转发:
socat TCP4-LISTEN:8080 TCP4:123.456.789.12:80
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它完美地工作:all http-requests localhost:8080将被重定向到123.456.789.12:80.
但是我怎样才能将这种转发用于请求https?
更新:我需要socatFirefox和远程服务器之间的单个进程.socat只是一个转发器(代理重定向器),仅此而已.像这样的东西:
Firefox -> socat -> server
------------>
https
Run Code Online (Sandbox Code Playgroud) 我发现默认情况下OS不会立即释放服务器关闭后服务器套接字使用的端口.通过SO_REUSEADDR在设置套接字时给出可以避免这个问题,但我不明白为什么保持端口一段时间是有用的.如果服务器关闭,套接字关闭,传输到该端口的任何数据都不会被处理吗?
我有一个简单的逻辑Java,它检查端口是否已被使用:
public static boolean isPortInUse(int port)
{
ServerSocket socket = null;
try {
socket = new ServerSocket(port);
socket.setReuseAddress(true);
} catch (Exception e) {
return true;
}
finally
{
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我是socket编程的新手,所以我无法理解"setReuseAddress"这里方法的用途.我已经通过了这个链接,但我没有明确它的目的.
sockets ×6
c ×2
java ×2
linux ×2
unix ×2
.net ×1
boost ×1
boost-asio ×1
c# ×1
c++ ×1
forwarding ×1
https ×1
jmx ×1
portability ×1
powershell ×1
restart ×1
reusability ×1
shutdown ×1
socat ×1
windows ×1