I have a simple socket program created in C (using Ubuntu), the connection works fine, server compiles and client provides the IP and port number.
But when the connection is established, the client can only send one message
and then the connection closes
. When the client sends the message, the server receives it and the program ends by itself
.
I tried to use a while loop
, but then it gives me an Error on binding
. Is there any way to make it infinite, so that when user enters exit
or some specific key/command
, the program ends.
server.c UPDATED with WHILE LOOP
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portNum, clien, n;
char buffer[256];
struct sockaddr_in serv_addr,cli_addr;
if (argc < 2)
{
fprintf(stderr, "\nno port provided");
exit(1);
}
sockfd = socket(AF_INET,SOCK_STREAM, 0);
if (sockfd < 0)
printf("\nprovide a valid port number\n");
bzero((char *)&serv_addr, sizeof(serv_addr));
portNum = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portNum);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
printf("error on binding");
while(1)
{
listen(sockfd,5);
}
clien = sizeof(cli_addr);
newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clien );
if (newsockfd < 0)
printf("=> Error on accepting...\n");
bzero(buffer, 256);
n = read(newsockfd, buffer, 256);
if (n < 0)
printf("error reading from socket...\n");
printf("%s\n", buffer);
n = write(newsockfd, "message received.", 58);
if (n < 0)
printf("cannot write from socket...\n");
return 0;
}
client.c UPDATED with WHILE LOOP
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
int main(int argc, char *argv[])
{
int sockfd,portno,n;
char buffer[256];
struct sockaddr_in serv_addr;
struct hostent *server;
//while(counter != 5)
// /{
if (argc < 3)
{
fprintf(stderr,"Usage %s hostname port...\n",argv[0]);
exit(1);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
printf("\error opening socket...\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"no such host...\n");
exit(0);
}
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(portno);
if (connect(sockfd, &serv_addr,sizeof(serv_addr)) <0 )
printf("\error connecting\n");
printf("your message:");
fgets(buffer, 256, stdin);
while(1)
{
n = write(sockfd,buffer,strlen(buffer));
}
if (n < 0)
printf("error writing to socket\n");
n = read(sockfd, buffer, 255);
if (n < 0)
printf("error reading from socket\n");
printf("%s\n", buffer);
return 0;
}
Thank you.
Best Answer
The problem with your server is that you immediately terminate whenever you receive a message. What you should do is keep on listening with the recv() function until the client disconnects. Here is one piece of code that should do the trick.
Disclaimer: However I haven't tested it, it's from an old project that I modified for you on the fly it's supposed to work but I'm not 100% sure it does, I have no time to test it right now but feel free to ask questions if there is something wrong, I'll try to correct it.
EDIT: trying to re-bing causes an error because the binding is already done and the port is already busy so you cannot "assign" an other program to this port therefore giving you an error. The only thing that you have to do is make sure that your server listens until the client disconnects from the server.
Also, it is possible that some of the code was made for c++ at some point, but the networking part should work just fine.
Feel free to try it out and comment if you have questions. Server.c:
As for the client, do a while loop until a certain time has passed or a given character or value is entered. Something like:
Hope it helps