This is a simple iterative client-server program. Where the server prints out "Received request" on successful establishment of connection.
server side
#define LENGTH 256
#define SERV_PORT 4000
#define LISTENQ 8
int main()
{
int listenfd, connfd, n;
socklen_t clilen;
char buf[LENGTH];
struct sockaddr_in cliaddr, servaddr;
//creation of socket
listenfd = socket (AF_INET, SOCK_STREAM, 0);
//creating socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// printf("\nServer running.. waiting for connections");
// listen(listenfd, LISTENQ);
for(; ;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
printf("\nReceived request");
//sleep(5);
}
return 0;
}
client side
#define LENGTH 256
#define SERV_PORT 4000
int main( int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[256];
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket failed");
exit(1);
}
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]);
if(hp == 0)
{
perror("gethost by name failed");
exit(1);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(4000);
if(connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
{
perror("\nconnect failed");
exit(1);
}
return 0;
}
When I run this multiple client-server code, the output for first client is different from the preceding clients. I need the first client to output like others. Can someone help?
When the first client establishes a connection with the server, the server doesn't output "Received request", where as, for the other clients do output "Received request".
You need to restore the listen() call. – EJP
Related
I have two programs: client and server. They're trying to find themselves in local network using broadcast.
Client sends simple packet on broadcast with SERVER_PORT (known before) and server prints info about connection, but when i tried this solution I found some strange behavaiour, when I uncomment last two lines of server.c server prints (one custom struct)
Connection from: 0.0.0.0 on port: 0
after commenting those lines everything works properly, am I missing something?
server.c
int broadcast_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in broadcast_addr;
broadcast_addr.sin_addr.s_addr = INADDR_ANY;
broadcast_addr.sin_port = htons(SERVER_PORT);
broadcast_addr.sin_family = AF_INET;
if (bind(broadcast_socket, (struct sockaddr *)&broadcast_addr,
sizeof(broadcast_addr))) {
perror("bind");
}
struct sockaddr_in recv_addr;
char buf[MAX_PACKET_SIZE];
socklen_t len;
if (recvfrom(broadcast_socket, buf, MAX_PACKET_SIZE, 0,
(struct sockaddr *)&recv_addr, &len) < 0) {
perror("recvfrom");
}
printf("Connection from: %s on port: %d\nMessage: %s\n",
inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port), buf);
/* struct network_packet packet; */
/* struct sockaddr_in my_addr; */
client.c
int find_server(struct sockaddr_in *out) {
struct sockaddr_in broadcast;
struct network_packet packet;
int yes = 1;
socklen_t len;
broadcast.sin_addr.s_addr = INADDR_ANY;
broadcast.sin_port = htons(CLIENT_PORT);
broadcast.sin_family = AF_INET;
int socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (bind(socket_fd, (struct sockaddr *)&broadcast, sizeof(broadcast))) {
perror("bind");
}
if (get_broadcast_addr(&broadcast.sin_addr)) {
return -1;
}
printf("Target address: %s\n", inet_ntoa(broadcast.sin_addr));
broadcast.sin_port = htons(SERVER_PORT);
broadcast.sin_family = AF_INET;
setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));
char buf[10] = "test";
sendto(socket_fd, buf, strlen(buf), 0, (struct sockaddr *)&broadcast,
sizeof(broadcast));
if (recvfrom(socket_fd, &packet, sizeof(packet), 0,
(struct sockaddr *)&broadcast, &len) < 0) {
perror("recvfrom");
}
struct sockaddr_in *sa = (struct sockaddr_in *)packet.data;
memcpy(out, sa, packet.header.packet_length);
return 0;
}
struct network_packet_header {
enum network_packet_type type;
int packet_length;
};
struct network_packet {
struct network_packet_header header;
unsigned char data[MAX_DATA_LENGTH];
};
You have to initialize the variable you pass as recvfrom's addrlen to the size of the address struct.
I'm trying to write a client-server program in C. For now I have a connection between the server and the client but for some reason nothing happens or prints after the "connected" print.
I've tried sample printing before and after the "connected" but nothing shows on my shell.
my server:
int main(void)
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);//Af_INet is protocol tcp np? ip? - this creates an empty socket
if (sockfd < 0)
{
printf("socket failed\n");
exit(0);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0)
{
printf("setsockopt failed\n");
exit(0);
}
// calls to bind(), listen() and accept() here
memset((char *) &serv_addr, 0, sizeof(serv_addr));
portno = 8888;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("bind failed\n");
exit(0);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
printf("accept failed\n");
exit(0);
}
//end calls
printf("[Server] Connected\n"); // nothing prints before or after this
int n;
char query[BUFFER_SIZE]={0};
char result[BUFFER_SIZE]={0};
char *hello = "Hello from client";
send(newsockfd, hello , strlen(hello) , 0 ); //write also doesn't work
printf("Hello message sent\n");
n = read( newsockfd, query, BUFFER_SIZE);
printf("%s\n",query );
close(newsockfd);
close(sockfd);
my client:
int main(void)
{
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("socket failed\n");
exit(0);
}
//get host and connect
portno = 8888;
server = gethostbyname("localhost");
if (server == NULL)
{
printf("gethostbyname failed\n");
exit(0);
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((void*)&serv_addr.sin_addr.s_addr, (void*)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("connect failed\n");
exit(0);
}
//end connect
printf("client here");//doesn't show on shell screen
printf("[Client] Connected\n");//shows on shell screen
int n;
char *hello = "Hello from client";
char query[BUFFER_SIZE]={0};
char result[BUFFER_SIZE]={0};
send(sockfd, hello, strlen(hello), 0);
printf("Hello message send\n");
n=read(sockfd,query,BUFFER_SIZE);
printf("%s\n",query);
close(sockfd);
I compile these with:
gcc -Werror -std=c99 server.c -o server
gcc -Werror -std=c99 client.c -o client
Also, I ran ./server before ./client , the shell screens show "Connected" on both client and server screens and that's it no matter what I write on the screen (either client's or server's)
Any help would be appreciated!
I would like to build a client - server model where, for any number of clients connected to the server, the server should send a broadcast Message. Below is the code which I implemented, it does not throw any error, but I could not see any communication happening between the server and the client. Please let me know, where is the problem in the code.
I would like to see the message passed from the server on the clients system.
/************* UDP SERVER CODE *******************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int udpSocket, nBytes, buflen;
char buffer[1024];
char string[1024];
int portNum;
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
int i;
/*Create UDP socket*/
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
portNum=atoi(argv[1]);
/*Configure settings in address struct*/
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5000);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.117");
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
/*Bind socket with address struct*/
int bStatus=bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (bStatus < 0) {
printf("error binding on server's port number\n");
exit(1);
}
/*Initialize size variable to be used later on*/
addr_size = sizeof serverStorage;
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(portNum); // this is where client is bound
clientAddr.sin_addr.s_addr = inet_addr("192.168.1.114");
while(1){
sprintf(buffer,"Hello Client");
buflen=strlen(buffer);
int bytesSent = sendto(udpSocket,buffer,buflen,0,(struct sockaddr *)&clientAddr, sizeof(clientAddr));
if (bytesSent < 0) {
printf("Error sending/ communicating with client\n");
exit(1);
}
printf("%s\n",buffer);
/*
// ****************************************************
memset(buffer, 0, 1024);
buflen=65536;
recvfrom(udpSocket,buffer,buflen,0,(struct sockaddr *)&serverStorage, &addr_size);
printf("Received from server: %s\n",buffer);
*/
}
return 0;
}
Below is the client code :
/************* UDP CLIENT CODE *******************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]){
int clientSocket, portNum, nBytes, buflen;
char buffer[1024];
char string[1024];
struct sockaddr_in serverAddr,clientAddr;
socklen_t addr_size;
/*Create UDP socket*/
clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
portNum = atoi(argv[1]);
/*Configure settings in address struct*/
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(portNum);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.117");
// memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
memset(&serverAddr,0,sizeof(serverAddr));
// binding
bind(clientSocket, (struct sockaddr *) &clientAddr, sizeof(clientAddr));
/*Initialize size variable to be used later on*/
addr_size = sizeof serverAddr;
while(1){
memset(buffer, 0, 1024);
buflen=65536;
recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size);
//recvfrom(clientSocket,buffer,buflen,0,NULL,NULL);
printf("Received from server: %s\n",buffer);
/*
//********************************************************************
sprintf(buffer,"Hello Client");
buflen=strlen(buffer);
sendto(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr,addr_size);
printf("%s\n",buffer);
*/
}
return 0;
}
At a high level there are a few things that need to be addressed. Given the code in the post has a server that initiates communication with the client following line needs to be modified (and related code for these)
On the server side:
sendto(udpSocket,buffer,buflen,0,(struct sockaddr *)&serverStorage,addr_size);
Essentially what's happening here is that udpSocket is bound to serverAddr and we are trying to sendto serverStorage (2nd last argument). The trouble here is that the serverStorage is not bound to anything. Basically sendto has the source right but not the destination.
On the client side:
recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size);
The clientSocket is not bound to anything so the system picks a random port where it will listen. In the recvfrom call, 2nd last argument captures the address details of the other side. Whereas in the code you have bound it to server's IP and port, it does not have any effect because it is filled in by the recvfrom call and returned.
To make things work here is what I'd suggest (you can add the details but have worked out the skeleton based on what you posted)
server_initiating_with_client.c
//...
int udpSocket, nBytes, buflen;
char buffer[1024];
int portNum;
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
/*Create UDP socket*/
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
portNum=atoi(argv[1]);
/*Configure settings in address struct*/
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5000); // Making sure server has a unique port number
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/*Bind socket with address struct*/
int bStatus = bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
if (bStatus < 0) {
printf("error binding on server's port number\n");
exit(1);
}
/*Initialize size variable to be used later on*/
addr_size = sizeof serverStorage;
/* Because server is initiating the communication here one needs to set the
* clientAddr and needs to know the port number of the client
*/
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(portNum);
clientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
while(1){
sprintf(buffer,"Hello Client");
buflen=strlen(buffer);
int bytesSent = sendto(udpSocket,buffer,buflen, 0,
(struct sockaddr *)&clientAddr,
sizeof(clientAddr));
if (bytesSent < 0) {
printf("Error sending/ communicating with client\n");
exit(1);
}
printf("Done sending %s\n", buffer);
sleep(1);
}
..
and on the client side something along these lines
//..
int clientSocket, portNum, nBytes, buflen;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_in clientAddr;
socklen_t addr_size;
/*Create UDP socket*/
clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
portNum = atoi(argv[1]);
/*Configure settings in address struct*/
memset(&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(portNum);
clientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&serverAddr, 0, sizeof(serverAddr));
/*Bind on client side as well because you are specifically sending something over
* to the client. Usually the server will know where to talk back to the client
* but in your example because of the reversed semantics this will be needed
*/
bind(clientSocket, (struct sockaddr *) &clientAddr, sizeof(clientAddr));
/*Initialize size variable to be used later on*/
addr_size = sizeof serverAddr;
while(1){
memset(buffer, 0, 1024);
buflen=65536;
recvfrom(clientSocket,buffer,buflen,0,(struct sockaddr *)&serverAddr, &addr_size);
printf("Received from server: %s\n",buffer);
sleep(1);
}
return 0;
The code can be simplified if you reverse your comm from client to server, thereby, eliminating the need for a fixed port number on the client side.
just make a few changes in it. Assign a socket length predefined (socklen_t *) structure to typecast length
n = recvfrom(sockfd, (char *)buffer, MAXLINE,MSG_WAITALL, (struct sockaddr *) &servaddr, (socklen_t*)&len);
socklen_t* convert a length into socket length.
Make these changes at both client-side as well as a server-side
.
I want to make a client and connect it to a server. I know that client process starts running before server so I do connection in infinite loop until it will be accept. Then I want to enter messages to client and send them to server, which will print them on screen. I removed all error detection from code to make it shorter, I know they have to be there. I am trying to do it like this, but server receives nothing and client can't do second connection.
Server
int main(int argc, char *argv[])
{
int sockfd, newsockfd;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(5000);
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0)
{
read(newsockfd, buffer, 255);
close(newsockfd);
}
close(sockfd);
return 0;
}
Client
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in serv_addr;
char buffer[256];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(5000);
while (1) {
while ((connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)) {
printf("trying to connect\n");
sleep(1);
}
printf("connected\nplease, enter a message\n");
scanf("%s", buffer);
write(sockfd, buffer, strlen(buffer));
}
close(sockfd);
return 0;
}
I don't know just how you've compiled your code but if you had set up the warning flag (-Wall in gcc) you would have gotten this warning
server.c: In function ‘main’:
server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
Acting by it, I changed, this ..
if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
To .. (notice the extra parentheses)
if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) {
I got no more additional warnings, and the server caught the client's message.
Here is the server I ran while debugging this (This is basically your code with slight alterations)
int sockfd, newsockfd;
socklen_t clilen;
char buffer[256];
int nbytes = 0;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
//serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(5007);
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (listen(sockfd, 5) <0) { }
clilen = sizeof(cli_addr);
if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen)) >= 0) {
while ((nbytes = read(newsockfd, buffer, sizeof(buffer)))<0) {
sleep(1);
}
printf("client sent: %s", buffer);
}
close(newsockfd);
close(sockfd);
return 0;
Another problem was that we have to create socket each time we do connect in client, like:
while (1) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
while ((connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)) {
printf("trying to connect\n");
sleep(1);
}
printf("connected\nplease, enter a message\n");
scanf("%s", buffer);
write(sockfd, buffer, strlen(buffer));
}
I created a server socket in C. This is the most basic stuff like what you would fine in a simple TCP server example. Server code is below. I also created a client socket that runs on the host machine. Code also below. However, for some reason the client is not able to connect to the server. The IP address I used is the same as the one under the entry eth0 from the "ip addr" command. The network adapter of the VM is a bridged connection.
The exact same code works when both client and server run on the same machine (the host).
Thank you!
Server code:
int sockfd;
int clientfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return EXIT_FAILURE;
}
printf("Socket descriptor is: %d\n", sockfd);
memset(&self, 0, sizeof (self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*) &self, sizeof (self)) != 0) {
perror("socket--bind");
return EXIT_FAILURE;
}
if (listen(sockfd, 20) != 0) {
perror("socket--listen");
return EXIT_FAILURE;
}
clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
Client Code:
int sock;
struct sockaddr_in server;
//struct sockaddr_in client;
struct hostent *hp;
//char buf[BUFFER_SIZE];
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die(6, "Opening stream socket");
printf("Client socket file descriptor is: %d\n", sock);
memset(&server, (char) 0, sizeof (server));
server.sin_family = AF_INET;
hp = gethostbyname(host_name);
if (!hp) {
//sprintf(buf, "%s: unknown host\n", host_name);
die(8, "%s: unknown host\n", host_name);
}
memcpy(hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons((u_short) SERVER_PORT);
/* Try to connect */
if ((connect(sock, (struct sockaddr *) &server, sizeof (server))) < 0)
die(7, "%s", "Failed to connect stream socket\n");