I have an application where, upon an external event, a socket is opened to a remote server using TCP and a string is sent over it. A new socket is created each time, then closed and shutdown after the data is sent.
Now I've been informed by a client of ours that they wish the source port to remain constant. In order to implement a small change to the code, I've tried using the SO_REUSEPORT and SO_REUSEADDR options in order to be able to re-bind a socket to the same source port as previous sockets. The first socket works fine, but subsequent connections do not. What could be the issue here?
Code: Select all
struct sockaddr_in destAddr;
destAddr.sin_addr.s_addr = inet_addr(remote_ip);
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons(remote_port);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0)
{
ESP_LOGE(TAG, "tcpClientTaskSocketAPI : Unable to create socket: errno %d", errno);
}
ESP_LOGI(TAG, "tcpClientTaskSocketAPI: Socket created");
int option_value = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &option_value, sizeof(int));
option_value = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option_value, sizeof(int));
struct sockaddr_in sourceAddr;
sourceAddr.sin_addr.s_addr = htonl(INADDR_ANY);
sourceAddr.sin_family = AF_INET;
sourceAddr.sin_port = htons(source_port);
err_v = bind(sock, (struct sockaddr *)&sourceAddr, sizeof(sourceAddr));
ESP_LOGW(TAG, "%d", err_v);
int err = connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0)
{
ESP_LOGE(TAG, "tcpClientTaskSocketAPI: Socket unable to connect: errno %d", errno);
}
ESP_LOGI(TAG, "tcpClientTaskSocketAPI: Successfully connected");
if(sock > 0)
{
send(sock, data, strlen(data), 0);
ESP_LOGE(TAG, "tcpClientTaskSocketAPI: Shutting down socket and restarting...");
shutdown(sock, 0);
close(sock);
}
vTaskDelete(NULL);