Reputation: 551
I have written a server and client program using socket in C in Linux.
Codes are given below:
Server Code:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
close(client_sock);
puts("I am at While loop");
while(1)
{
}
return 0;
}
Client Code:
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
close(sock);
while(1);
return 0;
}
when I run server code and then client code it works fine but when I terminate client code run it again (server code executed once only) it automatically connects to server without accept being called by server.
I don't want client to get connected until server calls accept() to connect with client.
I just want client to wait or give some timeout until server calls accept() to establish connection between them.
Output I am getting is below :
Server Output:
root@beaglebone:/home/Saad/test# ./server_test
Socket created
bind done
Waiting for incoming connections...
Connection accepted
I am at While loop
Client Output:
root@beaglebone:/home/Saad/test# ./client_test
Socket created
Connected
^C
root@beaglebone:/home/Saad/test# ./client_test
Socket created
Connected
I don't know why this is happening and how to resolve it.
UPDATE:
I have tried the answer below after some edits in client code I am facing same problem.
Client code:
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
char buf[1];
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int ret;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("192.168.1.2");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
if (ret < 0)
{
perror("connect failed. Error");
return 1;
}
recv(sock, buf, 1, MSG_WAITFORONE);
printf("%s",buf);
puts("Connected\n");
close(sock);
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
if (ret < 0)
{
perror("connect failed. Error");
return 1;
}
else
{
puts("Connected\n");
}
while(1);
return 0;
}
Client output:
root@beaglebone:/home/Saad/test# ./client_test_1
Socket created
1Connected
Socket created
Connected
Upvotes: 2
Views: 7011
Reputation: 311039
I don't want client to get connected until server calls accept() to connect with client.
Bad luck, that's not how TCP works. listen(socket_desc , 3)
creates a backlog queue, using the second parameter as a hint as to its length, which will be ignored in this case as it is too small. The purpose of this queue is to hold connections that have been completed by TCP but not yet accepted by the server application. Typical sizes vary from 50 to 500 or more, depending on the platform.
I just want client to wait or give some timeout until server calls
accept()
to establish connection between them.
Unimplementable. Why do you think you need this?
I don't know why this is happening and how to resolve it.
You can't resolve it, except by a pointless extra send/recv as per @IshayPeled's answer. It isn't a problem that needs resolving. If you think otherwise please tell us why. Every other TCP application ever written works this way. What's different about yours?
Upvotes: 1
Reputation: 2868
@EJP explained it well, if you want to fix you issue, use this code:
Client:
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
char buf[1];
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int ret;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
if (ret < 0)
{
perror("connect failed. Error");
return 1;
}
recv(sock, buf, 1, MSG_WAITFORONE);
puts("Connected\n");
close(sock);
while(1);
return 0;
}
Server:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
send(client_sock, "1", 1, 0);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
close(client_sock);
puts("I am at While loop");
while(1)
{
}
return 0;
}
On the client side:
I added a recv
call on the client side, that blocks until the server actually sends something.
On the server side:
I added a send
call right after the accept call. That makes sure only clients that have been accepted will continue their code path.
Upvotes: 3