what happen when you run client without server running? - c

I got an interview question in sockets in c programming
I got two files server.c and client.c
I was asked what will happen if you run a client when the server is not running : more specifically
run ./client localhost without running ./server in a different terminal
and I didn't know the answer (obviously it won't connect but what will happen I don't know)
they wanted an answer that was related to the sockets
when I checked in Wireshark to see if I can get some information I saw this:
the focus on the red record of the TCP sockets and the one record above it.
9999 is the port of the server
what is the meaning of every parameter here?
56020 ->9999 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM=1 TSval=736093598 TSecr=0 WS=128
and also what is the meaning of
9999 -> 56020 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
I tried to look for the meaning in google but didn't find results that related to sockets.
thank you very much in advanced!
code for the client.c
// to run in the terminal compile with
// gcc -o client client.c -Wall
// then run the following command:
// ./client localhost
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SIM_LENGTH 10
// #define IP_ADDRESS "127.0.0.1" // from the last part we put this in comment and resolve it with gethostbyname
#define PORT 9999
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in cli_name;
int count;
int value;
char *hostname;
char *hostaddr;
struct addrinfo *res;
struct sockaddr_in *saddr;
printf("Client is alive and establishing socket connection.\n");
printf("%d %s\n", argc, argv[1]);
if (argc != 2)
{
perror("Usage: hostnamelookup <hostname> error \n");
exit(1);
}
hostname = argv[1]; // hostname is the first argument
printf("Hostname is %s\n", hostname);
if (0 != getaddrinfo(hostname, NULL, NULL, &res)) // getaddrinfo is a function that returns a struct addrinfo* that
// contains a linked list of struct addrinfo (from nslookup.c)
{
fprintf(stderr, "Error in resolving hostname %s\n", hostname);
exit(1);
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("Error opening channel");
close(sock);
exit(1);
}
saddr = (struct sockaddr_in *)res->ai_addr; // get the address of the server socket address structure (from nslookup.c)
hostaddr = inet_ntoa(saddr->sin_addr); // get the IP address of the server (from nslookup.c)
bzero(&cli_name, sizeof(cli_name));
cli_name.sin_family = AF_INET;
cli_name.sin_addr.s_addr = inet_addr(hostaddr); // set the IP address of the client (from nslookup.c)
cli_name.sin_port = htons(PORT);
if (connect(sock, (struct sockaddr *)&cli_name, sizeof(cli_name)) < 0)
{
perror("Error establishing communications");
close(sock);
exit(1);
}
for (count = 1; count <= SIM_LENGTH; count++)
{
read(sock, &value, 4);
printf("Client has received %d from socket.\n", value);
}
printf("Exiting now.\n");
close(sock);
exit(0);
}
server.c
// to run in the terminal compile with
// gcc -o server server.c -Wall
// then run the following command:
// ./server
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SIM_LENGTH 10
#define PORT 9999
int main(void)
{
int sock; // socket descriptor
int connect_sock; // socket descriptor for the connection
struct sockaddr_in serv_name; // server socket address structure
socklen_t len; // length of the socket address structure
int count; // number of bytes received
sock = socket(AF_INET, SOCK_STREAM, 0); // create a socket
// check if the socket is valid
if (sock < 0)
{
perror("Error opening channel");
exit(1);
}
// initialize the server socket address structure
bzero(&serv_name, sizeof(serv_name)); // clear the structure
serv_name.sin_family = AF_INET; // set the family to Internet
serv_name.sin_port = htons(PORT); // set the port number
// check if the bind is successful
if (bind(sock, (struct sockaddr *)&serv_name, sizeof(serv_name)) < 0) // bind the socket to the server address
{
perror("Error on binding");
exit(1);
}
// listen for connections
if (listen(sock, 1) < 0) // listen for connections on the socket
{
perror("Error on listening");
exit(1);
}
len = sizeof(serv_name); // get the length of the socket address structure
connect_sock = accept(sock, (struct sockaddr *)&serv_name, &len); // accept a connection on the socket
// check if the connection is valid
if (connect_sock < 0)
{
perror("Error on accepting");
exit(1);
}
for (count = 1; count <= SIM_LENGTH; count++) // loop to send the data
{
write(connect_sock, &count, 4); // send the data
printf("Server has written %d to socket.\n", count); // print the data
}
close(connect_sock); // close the connection
close(sock); // close the socket
}

If the host on that IP is completely down and unreachable (or the destination port is effectively firewalled), then the client will retry initiating the three way handshake a few times before timing out and bubbling up an error to the socket application calling connect.
If the host is up, but not listening on the expected port, it will send back an RST in response to receiving SYN from the client. That will effectively tell the client to "go away, I'm not listening". And the TCP stack will again bubble up an error to the socket application to trigger its connect call to return an error.

Related

How come this c server isn't able to consume data sent with c client and get stuck on read system call?

This is the client :
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 1026
#define SA struct sockaddr
int main(){
int sockfd;
struct sockaddr_in servaddr, cli;
//CREATE SOCKET
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
//exit(0);
}
char buffw[]="Hello World";
int res;
res=write(sockfd,buffw,sizeof(buffw));
char buffr[10];
while( (read(sockfd,buffr,sizeof(buffr))) > 0 );
close(sockfd);
return 0;
}
And here is the server :
#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>
#include <sys/stat.h>
#include <fcntl.h>
#define SA struct sockaddr
#define PORT 1026
int main(){
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
//SOCKET CREATION
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr =htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
//BIND
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
//LISTEN
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
for(;;){
len = sizeof(cli);
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server accept failed...\n");
exit(0);
}else{
printf("New connection accepted !\n");
}
char buff;
//The read get stuck here without reading !!
while( ((buff=read(connfd,&buff,1))) > 0 ){
printf("%c",buff);
};
close(connfd);
}
return 0;
}
I examined the traffic with wireshark and the TCP protocol stack receives properly 12 Bytes of data ("Hello World"). However it seems the read function get stuck. This doesn't happen if for example I turn the write function inside the client into a loop :
while ( (write(sockfd,buffw,sizeof(buffw))) > 0 ) ;
In this case the server keeps receiving the 12 Bytes infinitely.
Anyone knows the reason why read is behaving like that ? Moreover If I try to send data from a browser it works correctly. I just don't understand why is not working...
Your client is sending 12 bytes (11 characters + null terminator), then reading whatever the server sends something, which is nothing. So the client is stuck on read() after sending and does not close the connection.
The server is reading from the client 1 byte at a time in a loop until the client disconnects, which doesn't happen. After 12 bytes have been read, there are no more bytes to read, so read() waits for new bytes to arrive, which will never happen.
So, you end up in a deadlock situation where the client is waiting on the server, and the server is waiting on the client. You will have to kill one of the programs, or disable the network adapter, to end the deadlock.
Since the client is sending the string's null terminator, you can have the server look for that terminator and break its reading loop once it arrives, eg:
while( read(connfd, &buff, 1) > 0 ){
printf("%c", buff);
write(connfd, &buff, 1);
if (buff == '\0') break;
}

Message which I sent from a client program to server program prints in client program C Linux

I learn how application works themself by Internet. I wrote a client program which sends a message to a server program, then that message should be printed in a server program, but this message prints into a client program. Here code server program and client program, also header file to redefine some types.
There are not any errors and warning while compiling, so I didn't send a compiling process.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>
#include "../main_values.h"
int main()
{
int socket_server = socket(AF_INET, SOCK_STREAM, 0); //create a socket server
int opt = 1;
setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //set an option to socket to
//if we ends working with
sockaddr_in addr_server; //socket connected with
addr_server.sin_family = AF_INET; //ip address, free ip
addr_server.sin_port = htons(2251);
addr_server.sin_addr.s_addr = inet_addr("127.0.0.222");
int stat = bind(socket_server, (sockaddr *)&addr_server, sizeof(addr_server)); //connecting ip addr and socket
if (stat == -1)
{
perror("ERROR");
}
sockaddr_in addr_client; //create the future client ip stucture
socklen_t len = 0;
listen(socket_server, 15); //set server socket into listening
int socket_client = accept(socket_server, (sockaddr *)&addr_client, &len); //connecting client ip with our socket
if (socket_client == -1)
{
perror("ERROR");
}
char msg[100];
int res = read(socket_server, msg, sizeof(msg)); //getting message from client
printf("MESSAGE FROM CLIENT: %s\n", msg); //printing message from client
shutdown(socket_server, SHUT_RDWR); //closing server socket
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/un.h>
#include "../main_values.h"
int main()
{
int socket_client = socket(AF_INET, SOCK_STREAM, 0); //create a client socket
int opt = 1; //set an option like in a server.c
setsockopt(socket_client, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
sockaddr_in addr_client; //making client ip structure
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(2250);
addr_client.sin_addr.s_addr = htons(INADDR_ANY);
int stat = bind(socket_client, (sockaddr *)&addr_client, sizeof(addr_client)); //connecting ip and client socket
if (stat == -1)
{
perror("ERROR");
}
sockaddr_in addr_server; //creating a server ip structure
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(2251);
addr_server.sin_addr.s_addr = inet_addr("127.0.0.222");
int socket_server = connect(socket_client, (sockaddr *)&addr_server, sizeof(addr_server));
if (socket_server == -1) //connecting to server
{
perror("ERROR");
}
char msg[] = "HELLO WORLD!!!!!"; //excample message
int res = write(socket_server, msg, sizeof(msg)); //sending a message to server
shutdown(socket_client, SHUT_RDWR);
return 0;
}
main_values.h
#pragma once
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
terminal_1
ch#ch:~/Рабочий стол/mainc.4/my_server$ ./server.out
MESSAGE FROM CLIENT:
ch#ch:~/Рабочий стол/mainc.4/my_server$
terminal_2
ch#ch:~/Рабочий стол/mainc.4/my_server$ ./client.out
HELLO WORLD!!!!!ch#ch:~/Рабочий стол/mainc.4/my_server$
int socket_server = connect(socket_client, (sockaddr *)&addr_server,
...
int res = write(socket_server, msg, sizeof(msg));
The return code of connect is 0 if the connect succeeded. Thus socket_server is 0. This means a write to file descriptor 0 is done, which is the equivalent to stdin and thus results into a write to the terminal.
The correct code would be to write to socket_client, not socket_server. The naming suggests that there is some confusion of what connect returns, i.e. it returns a status and not a new socket. Please see the documentation for connect for details.

C Socket Programming - Connecting to an External Source

I'm trying to get into socket programming with C and my problem is that no matter what I try I cannot get my client-server model to connect over the internet except through logging into my router and port forwarding the port I'm inputting in my program. Basically my server.c blocks and waits for a connection, then it sends the time of the server to the client once it connects. I've tried to open ports on both my machines like this:
sudo iptables -A INPUT -p tcp --dport 20001 -j ACCEPT
and I downloaded the iptables-persistent package that makes sure the rules stay on a reboot. iptables -L shows me that the ports are open on both machines, but the connection still times out. I know that somehow this is possible because Steam and Discord don't have to port forward anything and they still make it happen. I have a server at home so if the solution requires a 'middle man' server to facilitate a connection between two clients, then it won't be a problem for me. Also I am on two separate networks, so that's not the problem.
The server.c:
/* --- server.c --- */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
/* creates an UN-named socket inside the kernel and returns
* an integer known as socket descriptor
* This function takes domain/family as its first argument.
* For Internet family of IPv4 addresses we use AF_INET
*/
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(20001);
/* The call to the function "bind()" assigns the details specified
* in the structure 『serv_addr' to the socket created in the step above
*/
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
/* The call to the function "listen()" with second argument as 10 specifies
* maximum number of client connections that server will queue for this listening
* socket.
*/
listen(listenfd, 10);
while(1)
{
/* In the call to accept(), the server is put to sleep and when for an incoming
* client request, the three way TCP handshake* is complete, the function accept()
* wakes up and returns the socket descriptor representing the client socket.
*/
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
/* As soon as server gets a request from client, it prepares the date and time and
* writes on the client socket through the descriptor returned by accept()
*/
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
and client.c:
/* --- client.c --- */
#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>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
/* a socket is created through call to socket() function */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(20001);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
/* Information like IP address of the remote host and its port is
* bundled up in a structure and a call to function connect() is made
* which tries to connect this socket with the socket (IP address and port)
* of the remote host
*/
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
/* Once the sockets are connected, the server sends the data (date+time)
* on clients socket through clients socket descriptor and client can read it
* through normal read call on the its socket descriptor.
*/
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
This line is saying what port you're connecting to on the server
serv_addr.sin_port = htons(42020);
change it to the same port number as the server and it should work just fine.
serv_addr.sin_port = htons(20001);
#include <stdio.h>
#include "http.h"
#define MAX 4096
int main()
{
char s_msg[MAX], c_msg[MAX];
printf("%d", strlen(s_msg));
// Clean buffers:
memset(s_msg,'\0',sizeof(s_msg));
memset(c_msg,'\0',sizeof(c_msg));
char *msg = "GET / HTTP/1.1\r\nUser-Agent: Hellothere\r\nHost: HOSTNAME\r\n\r\n";
int soc = init_client();
int con = connection("HOSTNAME",80);
if(send(socket_desc, msg, strlen(msg), 0) < 0){
printf("Unable to send message\n");
return -1;
}
if (recv(socket_desc, c_msg , MAX, 0)<0)
{
printf("Failed to read from server\n");
return -1;
}
printf("Recieved from server : %s\n",c_msg);
return 0;
}
Using ngrok you need to use Host header

Writing to Socket

I am making a simple 1 to 1 server-client chat application using sockets.Basically there is a server which can communicate with a single client at a time.What I am trying to do is client should send a string to server and the server has to send it back to the client with changing the case of the string(upper to lower and vice-versa).The problem is the string is sent to the server but the response from the server never came on account of that the client is unable to send other string.
Output of the program:-
root#User:~/Desktop/Aadil/SystemPracticum/Programs/Assignment5# ./Server 4000
the message from client is message1
root#User:~/Desktop/Aadil/SystemPracticum/Programs/Assignment5# ./Client localhost 4000
enter the message message1
enter the message message2
Thank You
Here is my code
Server.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
void ChangeCase(char *string){
int i = 0;
while(string[i]){
// printf("converting\n");
if(string[i] <= 90 && string[i] >= 65)
string[i] += 32;
else
string[i] -= 32;
++i;
}
}
int main(int counter, char *string[]){
if(counter < 2){
perror("erro! please provide port no.\n");
}else{
int server_socket_file_descriptor,client_socket_file_descriptor,
port_no,message_length,client_length;
char buffer[256];//buffer to be used for storing messages
struct sockaddr_in server_address,client_address;
server_socket_file_descriptor = socket(AF_INET,SOCK_STREAM,0);
/*it creates new socket the first argument AF_INET is used for internet domain
and second argument SOCK_STREAM is used for stream socket
third argument 0 means the default protocol for stram socket which is tcp*/
if(server_socket_file_descriptor < 0)
perror("\t\t\t\t=====!!!cant create a socket!!!=====\n");
bzero((char*)&server_address,sizeof(server_address));//set all value to 0
//set port no. by converting port from char* to integer
port_no = atoi(string[1]);
/*now initialize the server_address
server_address is a struct of sockaddr_in type which has four field in it
we need to initialize 3 of them
*/
server_address.sin_family = AF_INET;
//convert port no. to network byte order
server_address.sin_port = htons(port_no);
//set server ip address to the machines ip address in my case it is 10.8.3.236
server_address.sin_addr.s_addr=INADDR_ANY;
/*now we need to bind the server with socket created*/
if(bind(server_socket_file_descriptor,(struct sockaddr*)&server_address,
sizeof(server_address)) < 0){
perror("\t\t\t\t\t====error in binding====\n");
return 0;
}
//since socket is bind correctly I am not checking for the error
listen(server_socket_file_descriptor,8);
/*listening to socket. 8 represent the maximum client that
can wait in queue to connect to the server*/
//we are done with the server :D
client_length = sizeof(client_address);
client_socket_file_descriptor = accept(server_socket_file_descriptor,
(struct sockaddr*)&client_address,
&client_length);
if(client_socket_file_descriptor < 0)
perror("\t\t\t\t unable to connect to client");
while(1){
bzero(buffer,256);
message_length = read(client_socket_file_descriptor,buffer,255);
if(message_length < 0)
perror("\t\t\t\t error in reading from socket\n");
printf("\t\t\t\tthe message from client is %s\n",buffer);
ChangeCase(buffer);
message_length = write(client_socket_file_descriptor,buffer,sizeof(buffer));
if(message_length < 0)
perror("\t\t\t\t error writing to socket\n");
}
return 0;
}
}
Client.c
#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>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int file_descriptor,message_length,port_no;
char Buffer[256];//to store the message
//to store the address of the server to which we want to connect
struct sockaddr_in server_address;
struct hostent *server;//hostent defines the host computer on internet
if(argc < 3){
printf("\t\t\t please provide ip address and port no.\n");
return 1;
}
port_no = atoi(argv[2]);
if((file_descriptor = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&server_address, '0', sizeof(server_address));
server_address.sin_family = AF_INET;
//convert port no. to network byte order
server_address.sin_port = htons(port_no);
//set server ip address to the machines ip address in my case it is 10.8.3.236
server_address.sin_addr.s_addr = INADDR_ANY;
if(connect(file_descriptor,(struct sockaddr*)&server_address,
sizeof(server_address))<0){
perror("error in connection\n");
return 1;
}
while(1){
memset(Buffer, '0',sizeof(Buffer));
printf("\t\t\t\t\tenter the message\n");
fgets(Buffer,255,stdin);
message_length = write(file_descriptor,Buffer,strlen(Buffer));
if(message_length<0)
perror("\t\t\t\terror in writing\n");
memset(Buffer,'0',sizeof(Buffer));
message_length = read(file_descriptor,Buffer,255);
if(message_length < 0)
perror("\t\t\terror in reading from buffer\n");
else{
printf("%s\n",Buffer);
}
}
return 0;
}
I suspect that the problem is located in this line in your server code:
message_length = write(client_socket_file_descriptor,buffer,sizeof(buffer));
Note that this line always sends 256 bytes back to the client. For a string like "message1", that means it will send back "MESSAGE1" followed by 248 NUL/zero bytes.
Depending on how the TCP stack decides to break up those bytes, your client's read() call may receive those bytes in different partial sequences, and if any partial sequence it receives starts with a NUL/zero byte, it will print out as an empty string.
In order to better see what's going on, you might replace this line in your client:
printf("%s\n",Buffer);
with something like this:
printf("[%s]\n",Buffer);
I'd also recommend changing your server to specify strlen(buffer) as the final argument to write() rather than sizeof(buffer).

Unable to connect with multiple client with my socket server program

My socket server program is mentioned below. It works fine with the single client but when I try to connect it with another client at the same time, I am unable to connect. But I have defined MAX_CLIENTS in my program as 2 but still why I am unable to connect with multiple clients? What is the correct process to connect with multiple client? Will I be able to connect with multiple client by modifying this code? Any possible fix?
Socket Server Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <error.h>
#include <strings.h>
#include <unistd.h>
#include <arpa/inet.h>
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
main (int argc, char **argv){
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof (struct sockaddr_in);
int data_len;
char data [MAX_DATA];
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket: ");
exit (-1);
}
printf("after socket");
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = INADDR_ANY;
bzero (&server.sin_zero, 8);
printf("after server");
if ((bind (sock, (struct sockaddr*)&server, sockaddr_len)) == -1)
{
perror ("bind");
exit (-1);
}
printf("after bind");
if ((listen(sock, MAX_CLIENTS)) == ERROR)
{
perror ("listen");
exit (-1);
}
printf("after listen");
while(1)
{
if ((new = accept(sock, (struct sockaddr*)&client, &sockaddr_len)) == ERROR)
{
perror ("accept");
exit (-1);
}
printf("after new");
printf("New client connected from port no %d and IP %s\n",ntohs(client.sin_port), inet_ntoa(client.sin_addr));
data_len = 1;
while (data_len)
{
data_len = recv (new, data, MAX_DATA, 0);
if (data_len)
{
send (new, data, data_len, 0) ;
data [data_len]='\0';
printf("Sent mesg: %s", data);
}
printf("after datalen");
}
printf("Client Disconnected\n");
close(new);
}
printf("after close new");
close (sock);
}
Your program is single-threaded, and only does one thing at a time. When you have accepted a socket connection from a client (in your outer while loop) you start communicating with that client (in your inner while loop), and you don't get back to the accept call until the first client has disconnected.
Either use threads, with one thread that waits for new connections and one additional thread for each client, waiting for input from that client, or use the select call, which lets you wait for input simultaneously from several different sources.

Resources