Background
Since TCP sockets are identified with src IP/port and dest IP/port, I thought that two having TCP clients on same IP address with same port is possible if each of them connects to different servers.
So I tested it on my Macbook
Two servers(A and B) are listing on different port number.
1st client is bound to some port(i.g. 1234) and connect to A.
2nd client is bound to same port(1234) and connect to B.
The result is that 1st client successfully connected to A, but 2nd client failed to connect to B with error code 48 which means "Address already in use"
Question
So I guess that theoretically multiple TCP sockets can bind to same port on same IP address if dest IP or port are different, but practically (or in real world) OS does not allow different TCP sockets to bind to same port on same IP address except allocating new socket for TCP connection request at server-side .
Would you mind to comment if I mistake?
How to run test code
Compile
gcc server.c -o server
gcc client.c -o client
Run
I tested like this
./server 9000
<-- A server with port number 9000
./server 8000
<-- B server with port number 8000
./client 9000 1234
<-- 1st client succeeded to connect to A with local port 1234
./client 8000 1234
<-- 2nd client failed to connect to B with local port 1234
Code
server.c
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h> // read(), write(), close()
#define MAX 80
#define SA struct sockaddr
// Function designed for chat between client and server.
void func(int connfd)
{
char buff[MAX];
int n;
// infinite loop for chat
for (;;) {
bzero(buff, MAX);
// read the message from client and copy it in buffer
read(connfd, buff, sizeof(buff));
// print buffer which contains the client contents
printf("From client: %s\t To client : ", buff);
bzero(buff, MAX);
n = 0;
// copy server message in the buffer
while ((buff[n++] = getchar()) != '\n')
;
// and send that buffer to client
write(connfd, buff, sizeof(buff));
// if msg contains "Exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}
// Driver function
int main(int argc, char **argv)
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
int port = atoi(argv[1]);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server accept failed...\n");
exit(0);
}
else
printf("server accept the client...\n");
// Function for chatting between client and server
func(connfd);
printf("close connection directly");
// After chatting close the socket
close(sockfd);
}
client.c
#include <arpa/inet.h> // inet_addr()
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h> // bzero()
#include <sys/socket.h>
#include <unistd.h> // read(), write(), close()
#include <errno.h>
#define MAX 80
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
long writeRes = write(sockfd, buff, sizeof(buff));
printf("wrtie result : %d\n", writeRes);
bzero(buff, sizeof(buff));
long readRes = read(sockfd, buff, sizeof(buff));
printf("read result : %d\n", readRes);
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}
}
int main(int argc, char **argv)
{
int sockfd, connfd;
struct sockaddr_in servaddr, cliaddr;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));
////////////////////////////////////////
// bind client socket to specific address
bzero(&cliaddr, sizeof(cliaddr));
// assign client IP, PORT
int cliport = atoi(argv[2]);
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
cliaddr.sin_port = htons(cliport);
// Binding client socket to given IP and verification
if ((bind(sockfd, (SA*)&cliaddr, sizeof(cliaddr))) != 0) {
printf("client socket bind failed...\n");
printf("Error code: %d\n", errno);
exit(0);
}
else
printf("client socket successfully binded..\n");
////////////////////////////////////////
// assign server IP, PORT
int serverport = atoi(argv[1]);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(serverport);
// connect the client socket to server socket
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");
// function for chat
func(sockfd);
// close the socket
close(sockfd);
}