Server / Client workflow with socket in C - c

I'm starting to learn unix basics at college, i've got an exercise which says something like:"build a client/server application in C in which: the server (tcp socket) print the ip of the client and the text given, and and it shutdown when receives "exit" as string from the client.
Now I've got conceptual problems, i've written these two C program (ignoring for now the text thing...)which i start in two different linux terminal, but the client do nothing, and the server got stuck. I don't understand the whole address thing, what should i put in there (in client)?
Long story short: I cannot establish a simple connection
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family= AF_INET;
mio_indirizzo.sin_port=htons(5200);
mio_indirizzo.sin_addr.s_addr = htonl(INADDR_ANY);
int fd = socket(PF_INET,SOCK_STREAM,0);
if (fd<0) perror("socket"),exit(1);
int b=bind(fd,(struct sockaddr *)&mio_indirizzo,sizeof(mio_indirizzo));
if(b<0) perror("bind"),exit(-1);
if((listen(fd,5))<0) perror("listen"),exit(-1);
while(1){
struct sockaddr indirizzo_client;
int fd2=accept(fd, &indirizzo_client,NULL);
if (fd2<0) perror("accept"),exit(-1);
printf("connection accepted\n");
close(fd2);
}
close(fd);
shutdown(fd,SHUT_RDWR);
}
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
int main (void){
int fd;
struct sockaddr_in mio_indirizzo;
mio_indirizzo.sin_family = AF_INET;
mio_indirizzo.sin_port = htons(5200);
inet_aton("Putted here the IP of my machine", &mio_indirizzo.sin_addr);
fd = socket(PF_INET, SOCK_STREAM, 0); // crea un socket
connect(fd, (struct sockaddr *) &mio_indirizzo, sizeof(mio_indirizzo)); // crea la connessione
close(fd); // chiude il socket
}

In your server, for accept():
struct sockaddr indirizzo_client;
int len = sizeof(indirizzo_client);
int fd2=accept(fd, &indirizzo_client, &len);
But actually, your program will just print "connection accepted" and quit. You may use select or threads to communicate between the client and the server.

Related

Chat Server Application not working using C programming

I have been trying to create a chat server and client model (where the server reads the message sent by client and replies back with a hello message) using C programming, but my code isn't working.
Here's my code:
Server side code
https://cl1p.net/server
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#define PORT 22341
#define MAXLINE 1024
int main(){
int sockfd;
int clientfd;
char buffer[MAXLINE+1];
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
perror("Socket creation failed at server end");
exit(1);
}
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(PORT);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if ((bind(sockfd,(struct sockaddr *) &servaddr,sizeof(servaddr))<0)){
perror("Error while binding at server side");
exit(2);
}
int len=sizeof(servaddr);
while (1){
memset(buffer,0,strlen(buffer));
listen(sockfd,5);
accept(sockfd,(struct sockaddr *) &servaddr,&len);
recv(clientfd,buffer,MAXLINE,0);
if (strncmp(buffer,"Exit",4)==0){
printf ("Server exiting \n");
break;
}
send(clientfd,(char *)"Hello",MAXLINE,0);
}
close(sockfd);
close(clientfd);
}
Client Code:
https://cl1p.net/client1
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#define PORT 22341
#define MAXLINE 1024
int main(){
int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_port=htons(PORT);
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
sockfd=socket(AF_INET,SOCK_STREAM,0);
char buffer[MAXLINE+1];
char buffer2[MAXLINE+1];
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while (1){
memset(buffer,0,sizeof(buffer));
memset(buffer2,0,sizeof(buffer2));
printf ("Enter a message \n");
fgets(buffer,MAXLINE,stdin);
send(sockfd,(char *)buffer,MAXLINE,0);
printf ("Bufer is %s\n",buffer);
if (strncmp(buffer,"exit",4)==0){
printf ("Client exiting");
exit(1);
}
recv(sockfd,(char *) buffer2,MAXLINE,0);
printf ("Data received at client side is %s\n",buffer2);
}
close(sockfd);
return 0;
}
On running this code,I get a segmentation fault at the server side and receive no data at the client side. Can someone please explain what's wrong with my code?

Sockets: connection refused

I made a TCP Client/Server and I can run it one time. But when I try to run it more than one time, it gives me the following error: "Connection refused". Here's my code.
Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
int connection_state = connect(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
if (connection_state == 0) {
printf("Connected with the server.\n");
}
else {
printf("Connection with the server failed. [%s]\n", strerror(errno));
}
char net_message[256];
recv(net_socket, net_message, sizeof(net_message), 0);
close(net_socket);
shutdown(net_socket, SHUT_RDWR);
return 0;
}
Server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
int net_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in net_addr;
net_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
net_addr.sin_family = AF_INET;
net_addr.sin_port = htons(3250);
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
listen(net_socket, 1);
struct sockaddr_in cl_addr;
int cl_size = sizeof(cl_addr);
int cl_socket = accept(net_socket, (struct sockaddr*)&cl_addr, (socklen_t*)&cl_size);
int loop = 1;
char net_message[256];
send(cl_socket, net_message, sizeof(net_message), 0);
close(net_socket);
close(cl_socket);
shutdown(net_socket, SHUT_RDWR);
shutdown(cl_socket, SHUT_RDWR);
return 0;
}
I've been trying to solve the problem by many ways but I'm a newbie. Thanks for the help in advance!
The problem is with your server lacking the SO_REUSEADDR socket option which leads to the bind() syscall failing. The reason is, that after a client disconnects from the server, the connection is still known by the system in TIME_WAIT state, to wait for late packets. These lead to the bind() to fail with EADDRINUSE if the above mentioned socket option is not set.
Use the following:
...
int one = 1;
setsockopt(net_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bind(net_socket, (struct sockaddr*)&net_addr, sizeof(net_addr));
...
and do error checks for all syscalls! That would have shown you the problem much earlier and had saved you much time.
Some more issues:
You are sending an uninitialized buffer net_message
A shutdown on a listen socket isn't sensible at all, since no connection is established on it (this here: shutdown(net_socket, SHUT_RDWR);)
The shutdown on the client socket has - if at all - to be performed before the close(cl_socket);. But it is not necessary at all in that case.

passing arguments to the bind() function

i have this programm which should only bind a socket to a port and i always get
failure while binding.
I can compile it without a problem.
should i add something to the servAddr?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
int main(int argc , char* argv[]){
if(argc!=2){
printf("Parameters : <server Port>");
}
in_port_t servPort=atoi(argv[1]);
int servSock;
if(servSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)<0){
printf("error socket");
}
struct sockaddr_in servAddr;
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(servPort);
if(bind(servSock,(struct sockaddr*) &servAddr,sizeof(servAddr)) < 0){
printf("failure while binding");
}
}
= has priority lower than <, add extra braces:
if((servSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
printf("error socket");}
Without these braces servSock is 1 or 0, that is definitely not what you want. Also note that without priviledges you can not bind to ports lower that 1024.

Socket Programming using command line arguments for port number and IP address

The below code takes command line arguments as input and makes a socket ready for listening for the incoming packets from client side, however it is not running at some stage getting halted as the port number entered through command line is not getting feed as the same,
Pls guide what could be the possible error
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include "p8log.h"
#include <errno.h>
#define FIRST_SIZE 1
#define SECOND_SIZE 6
#define THIRD_SIZE 16
int main(int argc, char* argv[])
{
/*some code*/
if (fd != NULL)
{
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
/*Create UDP socket*/
udpSocket = socket(PF_INET, SOCK_DGRAM, 0);
if (udpSocket==-1)
LERR("Error in creating the socket with the error number <%s>",strerror(errno) );
/*Configure settings in address struct*/
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons((int)*PORT);
serverAddr.sin_addr.s_addr = inet_addr(IPADDR);
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*Bind socket with address struct*/
return 0;
}
Execution of the program:
./a.out 11111 127.0.0.1
Output:
Arg Count=3
Arguments are=./UDPserver,11111,127.0.0.1
port num=11111
IP ADDR=127.0.0.1
-------------------------------------------------------------------
Client Side Code:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 11111
#define IPADDR "127.0.0.1"
int main(){
/*some code*/
}
In your server, PORT is a char*.
When you pass "11111", *PORT (a.k.a. PORT[0]) is '1', and (int)*PORT is most likely 49.
You need to convert to an integer, using for instance atoi.

Regarding a simple TCP based echo server using Sockets API

I am learning the Sockets networking API. In this process, I have written a simple Echo server that uses TCP. I wrote the code in such a way that, as long as the server is running, anything typed on the client's console should be echoed back to it. However, I am unable to achieve this. Although, for the first input, I get the echo, from next time onwards, I do not get any message.
I know, we can implement it to run for many clients using fork(), but I want to know the reason behind the blocking of the client, and if possible ways to correct it.
Here is the code for the client:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd;
char msg[MAXCOUNT];
char blanmsg[MAXCOUNT];
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
sfd = socket(AF_INET,SOCK_STREAM,0);
saddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);
saddr.sin_port = htons(5004);
connect(sfd,(struct sockaddr*) &saddr, sizeof(saddr));
for(; ;) {
memset(msg,0,MAXCOUNT);
memset(blanmsg,0,MAXCOUNT);
fgets(msg,MAXCOUNT,stdin);
send(sfd,msg,strlen(msg),0);
recv(sfd,blanmsg,sizeof(blanmsg),0);
printf("%s",blanmsg);
fflush(stdout);
}
exit(0);
}
Here is the code for the server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,nsfd,n,i,cn;
char buf[MAXCOUNT];
socklen_t caddrlen;
struct sockaddr_in caddr,saddr; //Structs for Client and server Address in the Internet
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure
saddr.sin_family = AF_INET; //Internet Address Family
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(5004);
bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr));
listen(sfd,1);
for(; ;) {
caddrlen = sizeof(caddr);
nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen);
cn = recv(nsfd,buf,sizeof(buf),0);
if(cn == 0) {
exit(0);
}
buf[cn] = '\0';
send(nsfd,buf,strlen(buf),0);
}
close(nsfd);
exit(0);
}
You shouldn't call accept within the loop on the server. Move the accept before the for loop on the server and it should work how you expect.
Calling accept in the loop like that will make the server block until a new connection comes in. Your client is only opening a single connection, so the server will block on the second call to accept.
Your code is doing precisely what you asked it to do. You told it to accept a connection, receive some data from that connection, send that data back to the connection, then accept another connection. That's what it's doing. I suspect you want to move the accept call outside the for loop.
I think you required a code which servers multiple clients as well as echo message to respective clients.
so just have a look to your code again and note down modification
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAXCOUNT 1024
int main(int argc, char* argv[])
{
int sfd,nsfd,n,i,cn;
char buf[MAXCOUNT];
socklen_t caddrlen;
struct sockaddr_in caddr,saddr;
//Structs for Client and server Address in the Internet
sfd = socket(AF_INET,SOCK_STREAM,0);
memset(&saddr,0,sizeof(saddr)); //Clear the Server address structure
saddr.sin_family = AF_INET; //Internet Address Family
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
saddr.sin_port = htons(5004);
bind(sfd, (struct sockaddr*) &saddr,sizeof(saddr));
listen(sfd,5);/*request queue size*/
while(1)
{//main loop for cuncorent server
caddrlen = sizeof(caddr);
nsfd = accept(sfd,(struct sockaddr*) &caddr,&caddrlen);
if(fork()==0)
{//only child code for serving a particular client
for(; ;) {//loop for reading and writing back msg cotineously
cn = recv(nsfd,buf,sizeof(buf),0);
if(cn == 0) {
exit(0);
}
buf[cn] = '\0';
send(nsfd,buf,strlen(buf),0);
}//serving loop ends
close(nsfd);
exit(0);
}//child code ends
}//main while loop ends
exit(0);
}

Resources