I'm making a client program in C that has to deal with this situation:
1- server program receives udp datagram in port no 8080 sent by client with a port number X
2- server creates a new socket (TCP) in port number X
3- using this TCP socket, server reads a string sent by the client
(running on localhost)
I don't need to make the server program, it's already done. The points 1 and 2 are covered, but I've been a couple of days trying to work out the 3rd point and I'm not able to make it work ><
The code I've got for the client is this:
#define MYPORT 8080
int main(int argc, char *argv[ ]) {
int sockfd;
/* connector’s address information */
struct sockaddr_in their_addr;
struct hostent *he;
int numbytes;
int sockfd2, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc != 3) {
fprintf(stderr, "Usage: %s <hostname> <message>\n", argv[0]);
exit(1);
}
/* get the host info */
if ((he = gethostbyname(argv[1])) == NULL) {
perror("Error obtaining the client. \n");
exit(1);
}
else printf("Client obtained\n");
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Error creating UDP socket\n");
exit(1);
}
else printf("UDP Socket done\n");
their_addr.sin_family = AF_INET;
printf("Port: 8080\n");
their_addr.sin_port = htons(MYPORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8);
sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd2 < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
//sending port where the TCP socket will be associated
//server client connects correctly to this port
//and the code it's working fine in this point
if((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
perror("Client-sendto() error lol!");
exit(1);
}
//port is sent, now let's connect to the port by tcp and write the string
//not working properly from now on
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(atoi(argv[2]));
if (bind(sockfd2,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
listen(sockfd2, 5);
accept(sockfd2, 0, 0);
printf("accepted!\n");
//sending the string to the TCP Port...
if((numbytes = sendto(sockfd2, "hi", 2, 0, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr))) == -1)
{
printf("Client-sendto()-TCP error\n");
exit(1);
}
if (close(sockfd) != 0) printf("Client-sockfd-UDP closing is failed!\n");
else printf("Client-sockfd-UDP successfully closed!\n");
if (close(sockfd) != 0) printf("Client-sockfd2-TCP closing is failed!\n");
else printf("Client-sockfd2-TCP successfully closed!\n");
return 0;
}
The code works for the first two steps, but in the last step, it seems it's not connecting well with the TCP port, because my client program ends but my server program says that he receives null.
And of course I'm always sending ports > 1024
Thanks in advance, any help will be so appreciated.
listen(sockfd2, 5);
accept(sockfd2, 0, 0);
printf("accepted!\n");
I haven't read all your code, but the above (at least) is wrong. You absolutely need to retain the return value of accept: it's the socket you need to write to!
accept returns a file descriptor for the new TCP socket that has just been created for communicating with the "server" in your case. You need to use that as the file descriptor you write your string to.
(The sendto call just after that, apart from using the wrong socket, is a bit suspicious since the server will have no way to determine how much data to read/where the message stops. Passing a length of 3 (to include the \0 byte, would be a bit less suspicious.)
Related
I am currently coding a small chat application in C for learning network.
I develop using the Transmission Control Protocol with socket in C. I was able to connect to my server with a client not coded by myself (on local network). Now telnet succeed to connect to my chat server(so with server and telnet client on the same computer) and I can send and receive message BUT my very simple client cannot connect to it.
Since the begining I use port 9002 and right now I am trying to connect with IPv6 address ::1.
Here the "accept client" code of my server:
int main(void)
{
//Create the socket
int sock = socket(AF_INET6, SOCK_STREAM, 0);
printf("Socket créer\n");
//Set up the socket interface
struct sockaddr_in6 sin6 = { 0 };
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(PORT);
sin6.sin6_addr = in6addr_any;
//Bind the socket on the port
if(bind(sock, (struct sockaddr *) &sin6, sizeof(struct sockaddr_in6)) == SO_ERROR)
{
perror("bind()");
errx(EXIT_FAILURE, "Fail to bind");
}
//Make the sockey listen the port
if(listen(sock, MAX_CLIENT) == SO_ERROR)
{
perror("listen()");
errx(EXIT_FAILURE, "Fail to listen");
}
printf("Socket listening\n");
int csock;
size_t clientID = 0;
--snip--
while(1)
{
struct sockaddr_in6 csin6;
memset(&csin6, 0, sizeof(struct sockaddr_in6));
int sin6size = sizeof(struct sockaddr_in6);
//Accept a communication
printf("Wait for communication\n");
csock = accept(sock, (struct sockaddr *) &csin6, &sin6size);
printf("Connection accepted\n");
char msg[16];
sprintf(msg, "CONNECTED - %zu\n", clientID);
send(csock, msg, sizeof(msg), 0);
printf("Client %zu connected\n", clientID);
//Handle client
--snip--
}
So this is a basic connection with socket using connected communication. The server handle several client in the while loop thanks to threading.
Here the code of the client:
void *sender(void *arg)
{
int socket = (int)(long)arg;
char buffer[BUFF_SIZE];
while(1)
{
scanf("%s", buffer);
send(socket, buffer, strlen(buffer), 0);
bzero(buffer, BUFF_SIZE);
}
}
int main(int argc, char *argv[])
{
if(argc < 2)
errx(EXIT_FAILURE, "Usage: ./client <server ip>\n");
//Create the socket
int sock = socket(AF_INET6, SOCK_STREAM, 0);
struct hostent *hostinfo = NULL;
hostinfo = gethostbyname2(argv[1], AF_INET6);
if(hostinfo == NULL)
errx(EXIT_FAILURE, "Can't connect to the server\n");
//Set up the socket interface
struct sockaddr_in6 sin6 = { 0 };
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(PORT);
sin6.sin6_addr = *(struct in6_addr *)hostinfo->h_addr;
if(connect(sock, (struct sockaddr *) &sin6, sizeof(struct sockaddr)) == SO_ERROR)
{
perror("connect()");
errx(EXIT_FAILURE, "Fail to connect");
}
printf("Connection established\n");
pthread_t sending;
if(pthread_create(&sending, NULL, sender, (void *)(long)sock) != 0)
printf("Fail to create a thread\n");
//Handle reception
char buffer[BUFF_SIZE];
int n;
while((n = recv(sock, buffer, BUFF_SIZE - 1, 0)) >= 0)
{
buffer[n] = '\0';
printf("%s", buffer);
}
printf("Erreur: %d\nConnection broken\n", n);
pthread_cancel(sending);
close(sock);
return EXIT_SUCCESS;
}
So I start the client with:
~ ./client ::1
The output is the following:
Connection established
Error: -1
Connection broken
While the server is still "Waiting for communication". This means that the server do not accept the connection but the client succeed to connect.
Thank you for you help.
It is probably already the connect(), which fails here:
if(connect(sock, (struct sockaddr *) &sin6, sizeof(struct sockaddr)) == SO_ERROR)
SO_ERROR is not meant to be used here, but as a socket option when retrieving the error when an asynchronous connect fails. A (synchronous) connect() returns -1 on error and sets errno, so do
if(connect(sock, (struct sockaddr *) &sin6, sizeof(struct sockaddr)) == -1) {
...
Later, the recv here:
while((n = recv(sock, buffer, BUFF_SIZE - 1, 0)) >= 0)
fails with errno ENOTCONN, since the connection failed beforehand.
The same SO_ERROR mistake is present at various locations in your server code; it is possible, that already the bind() there fails! The call to listen() will then autobind it to a free ephemereal port, so the call as well as the call to accept() will succeed.
Why can the call to bind() fail? You might have to set the socket option SO_REUSEADDR when (re-)starting the server, otherwise it might refuse to use a recently bound port if connections are still in TIME_WAIT state. Place this directly before the bind() call:
int one = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
This might help.
I have created a server and client to communicate through socket.
However, when I am running under localhost, client port number displays same as the number that client is binded to.
But if I run on different machine, client port number is different to the number that client is binded to.
Any suggestion on why?
The code for server.c
int main(int argc, char *argv[]) {
int socket_file_descriptor, port_number;
struct sockaddr_in server_address;
connection_t *connection;
pthread_t thread;
char *client_address;
int client_port;
struct hostent client;
//check for command line arguments
if (argc != 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
//create socket
socket_file_descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socket_file_descriptor < 0)
error("ERROR opening socket");
printf("Successfully opened socket\n");
//clear server adress
bzero((char *) &server_address, sizeof(server_address));
//obtain port number
port_number = atoi(argv[1]);
//bind socket to port
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(port_number);
if (bind(socket_file_descriptor, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
error("ERROR on binding");
printf("Successfully Binded on port %d\n", ntohs(server_address.sin_port)); //show correct port number
//listen on port
if(listen(socket_file_descriptor,5) < 0)
error("ERROR on listening");
//print message to show connection has been made
printf("Ready and Listening...\n");
//keep server alive with while loop
while(1) {
//accept incoming connections
connection = (connection_t *)malloc(sizeof(connection_t));
connection->addr_len = sizeof(&connection->address);
char ip[connection->addr_len];
connection->sock = accept(*sfd, (struct sockaddr *)&connection->address, &connection->addr_len);
connection->addr = (long)((struct sockaddr_in *)&connection->address)->sin_addr.s_addr;
connection->client_port_number = ntohs(((struct sockaddr_in *)&connection->address)->sin_port);
if(getsockname(connection->sock,&connection->address, &connection->addr_len) == -1) {
printf("Error getting client socket address: %s\n", strerror(errno));
} else {
//client_port_number = ntohs((struct sockaddr_in *)&connection->address).sin_port);
}
if(connection->sock <= 0) {
error("ERROR on accept");
free(connection);
} else {
if(pthread_create(&thread, 0, pthread, (void *)connection) < 0)
error("ERROR creating thread");
printf("Thread Created... Listening on Client:[%s:%d]\n",
inet_ntop(AF_INET,(struct sockaddr *)&connection->addr,ip,connection->addr_len),
connection->client_port_number);
pthread_detach(thread);
}
}
return 0;
}
And code for client.c
int main(int argc, char *argv[]) {
int socket_file_descriptor; //socket
int port_number, my_port_number; //server port number , client port number
struct sockaddr_in server_address, my_address; //server IP, client IP
struct hostent * server;
char buffer[256]; //buffer
if(argv < 3) { //command prompt arg [./myC localhost 12345]
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
port_number = atoi(argv[2]); //server port number = 12345
socket_file_descriptor = socket(AF_INET, SOCK_STREAM, 0); //socket() allows socket_file_descriptor to create socket
if(socket_file_descriptor < 0) {
error("ERROR opening socket");
}
printf("Successfully Opened Socket\n");
server = gethostbyname(argv[1]); //get IP (into network byte) of localhost
if(server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &server_address, sizeof(server_address)); //memset(server_address)
server_address.sin_family = AF_INET; //AF_INET = symbolic constant
bcopy((char *) server->h_addr, (char *)&server_address.sin_addr.s_addr, server->h_length);
server_address.sin_port = htons(port_number); //htons = 'hostbyte' to 'networkbyte' for type 'short'
printf("Server_Address_Port: %d\n", ntohs(server_address.sin_port)); //ntohs = 'networkbyte' to 'hostbyte' for type 'short'
//Bind client on port
my_address.sin_family = AF_INET;
my_address.sin_port = htons(my_port_number);
if (bind(socket_file_descriptor, (struct sockaddr *) &my_address, sizeof(my_address)) < 0)
error("ERROR on binding");
printf("Client_Address_Port: %d\n", ntohs(my_address.sin_port));
//Connecting to the Server
if(connect(socket_file_descriptor,(struct sockaddr *)&server_address, sizeof(server_address)) < 0) //connect to socket
error("ERROR connecting");
printf("Please enter the message: "); //command prompt requests [send file/ get file / send struct]
bzero(buffer,256);
fgets(buffer,255,stdin);
...
}
And On the Console for server.c (on different machine):
Successfully opened socket
Successfully Binded on port 1234
Ready and Listening...Thread Created... Listening on Client:[172.23.15.197:59540]
And On the Console for client.c :
Successfully Opened Socket
Server_Address_Port: 1234
Client_Address_Port: 32698
Please enter the message:
When server is run on the localhost, client port number holds same value as 32698 (which is a random port that client is binded to) as the client does.
Anything wrong with the code itself????
Thanks in advance.
when I am running under localhost, client port number displays same as the number that client is [bound] to.
Correct. It's the same thing.
But if I run on different machine, client port number is different to the number that client is [bound] to.
The only way that can happen is if the server or client is behind a NAT device.
I have a server-client system (concurrent server). I have different clients on different machines. I am trying to send a notification to particular clients. However, I have a problem as the clients all have the same socket descriptor. On both computers, the clients have a socket descriptor of 3 and at the server a sd of 5. Can someone please tell me how I can identify these different clients and why is this happening?
int main(int argc, char *argv[]) {
pid_t pid;
int buff_size = 1024;
char buff[buff_size];
int listen_fd, client_conn;
struct sockaddr_in serv_addr;
int server_port = 5001;
char remote_file[255];
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("Socket cannot be opened");
exit(1);
}
/*Turning off address checking in order to allow port numbers to be
reused before the TIME_WAIT. Otherwise it will not be possible to bind
in a very short time after the server has been shut down*/
int on = 1;
int status = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
(const char *) &on, sizeof(on));
if (status == -1) {
perror("Failed to Reuse Address on Binding");
}
// Initialise socket structure
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY; // Accept connections from any address
serv_addr.sin_port = htons(server_port);
// Bind the host address
if (bind(listen_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
< 0) {
perror("ERROR on binding");
exit(1);
}
// Start listening for the clients, here process will
// go in sleep mode and will wait for the incoming connection
listen(listen_fd, 5);
while (1) {
//Accepting client connection
client_conn = accept(listen_fd, (struct sockaddr *) NULL, NULL);
if (client_conn < 0) {
perror("Client was not accepted...");
exit(1);
}
if ((pid = fork()) == 0) {
close(listen_fd);
bzero(buff, buff_size);
while ((bytes_read = read(client_conn, buff, buff_size)) > 0) {
fclose(file);
}
}
//Terminating child process and closing socket
close(client_conn);
exit(0);
bzero(buff, buff_size);
}
//parent process closing socket connection
close(client_conn);
}
return 0;
}
After the server forks a child it does close(client_conn). When accept assigns a socket descriptor to the new connection, it uses the lowest closed descriptor. Since you closed the socket earlier, it can be used for the next client that comes in.
This isn't a problem, because the connections are being managed by the child processes. They each have their own descriptor 5, and they don't interfere with each other.
You can get the client address & port returned to you by accept. Currently you are passing a null
client_conn = accept(listen_fd, (struct sockaddr *) NULL, NULL);
however just add a few lines like
struct sockaddr_in serv_addr, cli_addr;
int len = sizeof(cli_addr);
client_conn = accept(listen_fd, (struct sockaddr *) &cli_addr, &len);
and you have the client info in cli_addr.sin_addr.s_addr and cli_addr.sin_port.
You can get the pid of the child processing the connection from the return code of fork. That should give you all the information you need to create a table.
I have written the following code as an intermediate to connect two programs. There is a server program running and a client program on two different systems. This code is expected to act as an intermediate between these two programs.
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
//Connect with program on server side
char * serv_con(char app_data[50])
{
int sock, bytes_recieved;
char send_data[1024];
char *recv_data = malloc(1024);
struct hostent *host;
struct sockaddr_in server_addr;
host = gethostbyname("10.47.3.249");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(3128);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
perror("Connect");
exit(1);
}
bytes_recieved=recv(sock,recv_data,1024,0);
recv_data[bytes_recieved] = '\0';
send(sock, app_data, 50, 0);
return recv_data;
//close(sock);
}
//Connect with client app
char * cli_con(char ser_data[50])
{
int sock, connected, bytes_recieved , true = 1;
char send_data [1024];
char *recv_data = malloc(1024);
struct sockaddr_in server_addr,client_addr;
int sin_size;
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(5000);
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 bind1");
exit(1);
}
if (listen(sock, 5) == -1)
{
perror("Listen");
exit(1);
}
sin_size = sizeof(struct sockaddr_in);
connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size1);
printf("\n I got a connection from (%s , %d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
bytes_recieved = recv(connected,recv_data,1024,0);
recv_data[bytes_recieved] = '\0';
send(connected, ser_data,50, 0);
//close(sock);
}
int main()
{
char *ser_data, *app_data;
int pid = fork();
while(1)
{
if(pid == 0)
app_data = serv_con(ser_data);
else
ser_data = cli_con(app_data);
}
}
It works fine until the client side app runs. But as soon as the client side app runs, the code exit giving the error:
Unable to bind: Address already in use
I got a connection from (192.168.0.3 , 45691)
What modification should I make in the code to rectify this error? I am working on linux. Thanks in advance.
EDIT:
I have removved the comment from close(sock)and added close(connect) in the function cli_con. The code on the client side is given below:
int sock, bytes_recieved;
char send_data[1024],recv_data[1024];
struct hostent *host;
struct sockaddr_in server_addr;
host = gethostbyname("192.168.0.2");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5555);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
perror("Connect");
exit(1);
}
while(1)
{
//necessary codes
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
close(sock);
goto connct;
}
}
But now on running, the first program doesnot exit but doesnot even print
I got a connection from (192.168.0.3 , 45691)
But just keeps on running without printing ANY messages. But on the other hand, the client exits showing the error:
Connect: Connection reset by peer
What should I do now?
When a client disconnects you create a new server socket and bind it to the same port. If the server side socket was not closed the port is still in use, so bind fails.
Usually the server side of a socket program has a loop around accept to allow it process connections from many clients. This way bind and listen are called only once.
while (connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size1)) {
printf("\n I got a connection from (%s , %d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
bytes_recieved = recv(connected,recv_data,1024,0);
recv_data[bytes_recieved] = '\0';
send(connected, ser_data,50, 0);
close(connected);
}
It means you're trying to listen on port 5000, but there is already a program listening on that port (possibly an earlier version of your program which didn't close the port properly.) Change the port number to another value, or close any application listening on the port.
Since you're under Linux, you can use "netstat -nlp" as root to see what programs have which ports open.
One pointer for you is that, you should close both the listen socket and the socket which you obtain from the accept call.
close(connected);
close(sock);
Also, the socket takes sometime to be freed by the OS after it's usage and so, it might fail with an "Address already in use" error. You can check again properly in your code if your SO_REUSEADDR part of the code is executing properly.
Also, since you can try to add the listen socket creation code in your main function itself and pass it as an argument to cli_con function. Commonly followed mechanism is to create one listen socket and use it to accept multiple connections from client.
I hope in your original code you have proper memory allocation, initialization etc for ser_data & app_data.
This is the main code of my server program in C:
int main(int argc, char** argv)
{
int sock, connected, bytes_received, true = 1;
struct sockaddr_in server_addr, client_addr;
int sin_size;
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(atoi(argv[1]));
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 5000");
fflush(stdout);
while (1)
{
pthread_t child;
sin_size = sizeof (struct sockaddr_in);
connected = accept(sock, (struct sockaddr *) &client_addr, &sin_size);
printf("\n I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
threadInfo info;
info.argumentsPassedToCode = argv;
info.connected = connected;
pthread_create(&child, NULL, interpretMessage, &info);
}
close(sock);
return 0;
}
My server always prints out the IP of the incoming connection, and the port that it is coming in from. I noticed that the ports are always increasing.
Is this normal? If not, what am I doing wrong?
If my server runs for a long time, will it run out of ports? If so, what will happen?
If your server is working, you're not doing anything wrong. Source ports aren't guaranteed to follow a pattern, they just exist to complete the connection tuple, (source port, source address, dest port, dest address).
Ports are reused once connections close, so you should be okay.
TCP has a state called TIME_WAIT which is used to make sure that everything have been sent and received properly before cleaning up the socket. This happens after you have closed the socket in you code. The time that a socket is in the TIME_WAIT state depends on the OS.
That's why you don't get the same port again for client connections.
You can read more about the state here: https://stackoverflow.com/questions/41602/how-to-forcibly-close-a-socket-in-time-wait
1) Yes; the next available port is selected. It can be the same port (if the prev socket was freed already by kernel), it can be the next free one or any other port which is free, from 1024 to 65535 (first 1024 are reserved as you know); In your case you are seeing a different client port number because either you are not properly closing the client socket or the previous socket is still lingering when you are making the next connection or you are just making multiple parallel connections
2) If you are not properly shutting down the sockets, you will (probably first run out of file descriptor if you have lower default per-process limits which is ... 1024 fds per proc?) ; If you do tear them down correctly then you'll be fine