sockets programming: sending and receiving different data to different clients in C - c

I have written a basic client server code in c socket programming using the TCP/IP protocol but i cant figure out how to make it connect to different clients and send/receive different data to and from them as a function to the client (meaning if its the first client send him that data and if its that client send him the other data) and so on.
This is the only results i have found were sending the same data to different clients.
Current Server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
int main() {
char server_message[100] = {0};
int server_socket = 0;
int client_socket = 0;
struct sockaddr_in server_address;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 2);
client_socket = accept(server_socket, NULL, NULL);
printf("Please enter a massage:");
fgets(server_message, 100, stdin);
send(client_socket, server_message, sizeof(server_message), 0);
close(server_socket);
return 0;
}

By using original code from geeksforgeeks and Myst comment we can solve it.
You have one server that serves on local host 127.0.0.1, and can have multiple clients for this example i assume 5 clients are enough.
Run server once, and run many client to connect seprately to that server.
Server.c
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
#define STRING_SIZE 100
#define BUFFER_SIZE 100
int main(int argc, char const *argv[])
{
int server_fd, new_socket[5], valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
for (int i=0;i<5;i++){
if ((new_socket[i] = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read(new_socket[i], buffer, 1024);
printf("%s\n", buffer);
char send_buf[STRING_SIZE] = "hello";
char buf[BUFFER_SIZE]={0};
sprintf(buf, "%d", i);
strcat(send_buf, buf);
send(new_socket[i], send_buf, strlen(send_buf), 0);
//printf("Hello message sent\n");
}
return 0;
}
Client.c
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
//printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n", buffer);
return 0;
}
Run
After compiling codes with gcc client.c -o client and gcc server.c -o server
Open one terminal for server and start server by run ./server.
Now you can connect many client [up to 5] to it by running ./client.

Related

raspberry pi websocket client program hangs when connected to raspberry pi access point

I have a simple websocket program where a server and client exchange a message and then exit, taken from a geeks for geeks tutorial:
https://www.geeksforgeeks.org/socket-programming-cc/
server.c:
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
return 0;
}
client.c:
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
printf("$");
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
printf("#");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
printf("#");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
//CURRENT IP IS RPI4 IP
if(inet_pton(AF_INET, "192.168.0.12", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
printf("!\n");
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
My raspberry pi 4 is the server and my raspberry pi 3 is the client. On my normal home wifi network this program executes exactly as expected.
However I have turned my RPI4 into a standalone wifi access point using this tutorial: https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
When I connect the RPI3 client to the RPI4 network, and run the server and then the client program it hangs and seems like it isn't even running the first line of code and printing the "$", (this may not be the case as the assembler may move the first print statement somewhere else in execution).
I'm assuming this isn't a problem with my either of my programs but a problem with either the RPI4 access point or the RPI3's connection to the access point, but I know very little about networking. Can someone help me troubleshoot and pinpoint what the problem is?

TCP/IP server using c

I want to make a server-client programm.The first thing i can't find is to make the server never shut down and accept each client.I put a while(1) on my server to run but after 3 connections to one client my server stops accepting other connections and i delete this while.I cant find how to build this think.Also i want to create TCP/IP socket so am i making the socket with the right way?
Im working on ubuntu at Visual Studio Code.
Server:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define PORT 8080
int main(int argc,char* argv[]){
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char *hello = "Hello from server";
while(1){
char buffer[1024] = {0};
printf("Server\n");
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt,
sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 1) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Listening...\n");
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0) {
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
}
return 0;
}
My client so far:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define PORT 8080
int main(int argc,char* argv[]){
char* command = (char*) malloc(15*sizeof(char));
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
printf("Client\n");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
You have to put the loop only around the code, which accepts the clients. The server socket itself is only created once.
// Creation of server socket(), bind(), listen()
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
}
Furthermore, you should close the client socket at the end of the while block after the communication is finished (i.e. after the printf("Hello message sent\n");:
close(new_socket);
And note, that the clients are served serially this way. They can connect concurrently, but only one client is served at a time. If you need concurrent handling, you can for example fork() several processes, each handling one client, or handle multiple clients in one thread using poll() or select().

Socket Program in C++ to send a message back and forth between server and client

I am Trying to make a C/C++ Project using Socket Programming.
For this I need Client and Server to sent a index of array back and forth to each other.
So Client will next a index of array and server will sent another index of array until the game is over. (Yeah we are trying to make a game.)
I have written (copied from gfg) code for it but it's not working properly.
The Server for some reason didn't receive the second message. So, We kind of stuck in a deadlock.
Any idea what I did wrong??
Server.cpp
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *msg = "0";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
int i=0;
while(i<10)
{
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , msg , strlen(msg) , 0 );
printf("Message sent\n");
i++;
}
return 0;
}
Client.cpp
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *msg="0";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
int i=0;
while(i<10)
{
send(sock , msg , strlen(msg) , 0 );
printf("Message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
i++;
}
return 0;
}
Edit: It will be really nice if somebody can tell me how to sent an integer instead of a string.

Socket programming in c connection failed

Trying to practice socket programming in c. Been hitting an error of Connection Failedbut not sure why. I included both the server and client code. I believe the problem is with connect.
Also, i run the client first then run the server. Is that the right way to compile it?
//CLIENT
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
//SERVER
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
return 0;
}

socket connection failure

I am beginner in socket programming and reading Linux Network Programming book. I decided to implement client-server connection as shown in the book. Server program is run on Ubuntu 14.04 machine and client code is run from Mac machine. The server code is the following
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
const char message[] = "hello, world\n";
int main()
{
int sock = 0;
int port = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
fprintf(stderr, "failed\n");
else
printf("connection is establisshed\n");
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY );
server.sin_port = 3500;
int status = bind(sock, (struct sockaddr*) &server, sizeof(server));
if (status == 0)
printf("connection completed\n");
else
printf("problem is encountered\n");
status = listen(sock, 5);
if (status == 0)
printf("app is ready to work\n");
else
{
printf("connection is failed\n");
return 0;
}
while (1)
{
struct sockaddr_in client = { 0 };
int sclient = 0;
int len = sizeof(client);
int childSocket = accept(sock, (struct sockaddr*) &client, &len);
if (childSocket == -1)
{
printf("cannot accept connection\n");
close(sock);
break;
}
write(childSocket, message, strlen(message));
close(childSocket);
}
return 0;
}
As for client side i wrote the following code
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char* argv[])
{
int sock = 0;
int port = 0;
struct sockaddr_in servaddr;
sock = socket(AF_INET, SOCK_STREAM, 0);
int status = 0;
char buffer[256] = "";
if (sock == -1)
{
printf("could not establish connection\n");
exit(1);
}
port = 3500;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(port);
status = connect(sock, (struct sockaddr*) &servaddr, sizeof(servaddr));
if (status == 0)
printf("connection is established successfully\n");
else
{
printf("could not run the app\n");
exit(1);
}
status = read(sock, buffer, sizeof(buffer));
if (status > 0)
printf("%d: %s", status, buffer);
close(sock);
return 0;
}
To get IP address of client machine I run ifconfig from terminal an get inet_addr 192.168.1.165 value. Now when I pass that address string as command line argument I get message that app is not running message. There is problem with address that I got, as I understand. So what is the problem?
Thanks in advance
Most probably the server does not listen on the port you are assuming, that is 3500.
To fix this, change this line:
server.sin_port=3500
to be
server.sin_port = htons(3500);
(To monitor which process is listing on which address:port you might like to use the netstat command line tool. In your case probably using the options -a -p -n )
Also on recent systems accept() expects a pointer to socklen_t as last parameter, so change this
int len=sizeof(client);
to be
socklen_t len = sizeof client; /* sizeof is an operator, not a function¨*/

Resources