On Ubuntu systems, when a process occupies port 9999 and the port remains unavailable due to TIME_WAIT state after the process terminates, preventing new processes from binding to it, you can implement several solutions:
Solution 1: Implement SO_REUSEADDR Socket Option
Configure your application code with the SO_REUSEADDR option to permit immediate reuse of ports in TIME_WAIT condition. This approach works across various network programming environments.
Node.js Implementation
const http = require('http');
const app = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Server running on port 9999\n');
});
app.listen({
port: 9999,
host: '0.0.0.0',
reuseAddr: true // Enable address reuse
}, () => {
console.log('Application listening on port 9999');
});
Python Socket Configuration
import socket
import time
def create_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Enable address reuse
server_socket.bind(('0.0.0.0', 9999))
server_socket.listen(10)
print("Server initialized on port 9999")
try:
while True:
client_connection, client_address = server_socket.accept()
print(f"Incoming connection from {client_address}")
client_connection.close()
except KeyboardInterrupt:
print("Shutting down server...")
finally:
server_socket.close()
if __name__ == "__main__":
create_server()
This approach prevents the TIME_WAIT port blocking issue effectively.
Solution 2: Manual Port Release Procedures
When ports remain occupied, execute these manual release steps:
- Identify the occupying process
sudo lsof -i :9999
Alternatively:
sudo ss -tulnp | grep 9999
- Forcefully terminate the process
sudo kill -9 <PROCESS_ID>
Replace <PROCESS_ID> with the actual process identifier.
- Check TIME_WAIT status
ss -tan | grep 9999
- Force termination of TIME_WAIT connections
sudo fuser -k 9999/tcp
Solution 3: Linux Kernel Parameter Optimization
To globally minimize the duration ports remain in TIME_WAIT state, adjust kernel parameters:
- Reduce TIME_WAIT retention period
sudo sysctl -w net.ipv4.tcp_fin_timeout=8
The default value is 60 seconds before releasing TIME_WAIT connections.
- Enable rapid reuse of TIME_WAIT ports
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
⚠️ Note: tcp_tw_recycle has been deprecated since Linux 4.12. Use tcp_tw_reuse=1 for newer systems.
- Make changes persistent
Add parameters to/etc/sysctl.conf:
echo "net.ipv4.tcp_fin_timeout=8" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_tw_reuse=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Solution 4: Utilize SO_LINGER for Immediate Port Release
In low-level programming environments like C/C++, employ the SO_LINGER option to immediately release ports upon process closure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main() {
int socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);
struct linger linger_options;
linger_options.l_onoff = 1; // Enable linger
linger_options.l_linger = 0; // Linger time = 0
setsockopt(socket_descriptor, SOL_SOCKET, SO_LINGER, &linger_options, sizeof(linger_options));
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9999);
server_address.sin_addr.s_addr = INADDR_ANY;
bind(socket_descriptor, (struct sockaddr*)&server_address, sizeof(server_address));
listen(socket_descriptor, 5);
printf("Server active on port 9999...\n");
while (1) {
int client_socket = accept(socket_descriptor, NULL, NULL);
if (client_socket > 0) {
printf("Connection received\n");
close(client_socket);
}
}
close(socket_descriptor);
return 0;
}
This SO_LINGER configuration immediately releases the port upon close() execution, bypassing the TIME_WAIT state entirely.
Solution Comparison Matrix
| Solution Method | Applicable Scenarios | Recommendation Level |
|---|---|---|
| Implemetn SO_REUSEADDR | Modifiable codebase, TIME_WAIT prevention | ✅ Recommended |
| Manual Port Release | Temporary resolution of occupancy issues | ⚠️ Requires manual intervention |
| Kernel Parameter Adjustment | Affects global TCP port release behavior | ⚠️ Impacts entire system |
| Use SO_LINGER | Low-level C/C++ programming environments | ✅ Recommended (C/C++ specific) |
Optimal Implementation Strategy
- Code-level approach: Implement
SO_REUSEADDR - System optimization: Adjust
tcp_fin_timeout - Emergency procedures: Manual release (
fuser -k 9999/tcp)
These approaches eliminate the problem of ports remaining locked in TIME_WAIT state for extended periods.