I'm trying to program a simple client and server using sockets in C. Both the client and server are running Ubuntu. The server is broadcasting an ad-hoc network that the however I cannot seem to get the client to connect to the server despite being able to ping it from terminal.
The code I'm using for the server and client are adapted from an online source and are as such:
#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 , new_socket , c;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//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)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket<0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Reply to the client
message = "Hello Client , I have received your connection. But I have to go now, bye\n";
write(new_socket , message , strlen(message));
return 0;
}
Client
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("192.168.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected\n");
//Send some data
message = "GET / HTTP/1.1\r\n\r\n";
if( send(socket_desc , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
return 0;
}
The IP address was obtained by running ifconfig on the terminal of the server and looking at its inet addr value.
Additionally I've also disabled the firewall on both the client and the server by running sudo ufw disable in the terminal. Errno also outputs connection refused.
Can anyone please help me with this?
Your server listens to port 8888 and client tries to connect to port 80, both server.sin_port = htons( x ); must use the same port number.
Instead of directly using inet_addr("192.168.0.1");
use
struct sockaddr_in6 ser_address;
inet_pton(AF_INET,"192.168.0.1",&ser_address.sin.addr);
Note: We cannot use presentation style address in the codes when passing it to socket functions
Related
I'm trying to make an echo client server in C. The problem is, when I start the server and run the client code, in client shell it says "Connected" but in server shell it still says "Waiting for connection". (Server doesn't say "accept failed". It says "Waiting for connection" forever). I think server is not accepting client and therefore if I write anything from client shell it doesn't come back.
I would appreciate if I can get any help.
Here is server code:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
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("Socket couldn't created\n");
}
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");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3)
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while(1)
{
//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");
//Recieve message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0))>0)
{
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
Here is the client code:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[1000];
//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");
return 1;
}
puts("Connected\n");
//Keep communicating with server
while(1)
{
printf("Enter message: ");
scanf("%s", message);
//Send some data
if(send(sock, message, strlen(message), 0)<0)
{
puts("Send failed");
return 1;
}
//Recieve a reply from server
if( recv(sock, server_reply, 1000, 0)<0)
{
puts("recv failed");
}
puts("Server reply: ");
puts(server_reply);
bzero(message, 1000);
bzero(server_reply, 1000);
}
close(sock);
return 0;
}
You accept new clients in a infinite loop. So even if a client is detected the code will wait for an other client to connect.
If you want to make a single client server you can just remove the loop around the accept(). Example here
If you want to make a multiple client server you can thread your accept and store all your opened file descriptor. Example here
In your server code you never leave this infinite loop:
while(1)
{
//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;
}
}
You should either fork/thread or use the select function.
I am developing a simple server-client program where the client sends a number to the server and the server sends the number back.
I am trying to implement multithreading to it so multiple clients can send numbers.
The problem is that when a second client connects the 1st one freezes when about to receive the data back.
I have tried many things so far, but nothing worked.
I will post my code below if anyone can help me with it.
This is the server:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<fcntl.h> //close
void *thread_function(void *arg);
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[20000]="0";
int len=256;
int i=0;
char message[] = "Hello World";
int main() {
int res;
pthread_t a_thread;
void *thread_result;
//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...");
for(;;){
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");
printf("Client connected with IP: %s\n", inet_ntoa(client.sin_addr));
pthread_create(&a_thread, NULL, thread_function, (void *)message);
pthread_detach(a_thread);
}
// return 0;
}
//-------------------------------------------------
//-------------------------------------------------
void *thread_function(void *arg) {
//Receive a message from client
while((read_size = recv(client_sock , client_message , 2000 ,0)) > 0 )
{
len=strlen(client_message);
//Send the message back to client
send(client_sock , client_message ,2000,0);
fflush(stdin);
fflush(stdout);
puts(client_message);
strncpy(client_message,"0",sizeof(client_message) - 1);
}
}
And this is the client:
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<fcntl.h> //close
int main(int argc , char *argv[])
{
int n;
char sn[200];
int sock;
struct sockaddr_in server;
char message[2000] , server_reply[2000];
int i=0;
char user[20];
char pass[20];
int sig;
//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");
//keep communicating with server
n=1;
while(1)
{
printf("Enter message : ");
strncpy (message,"0",sizeof(message) - 1);
// itoa(n, sn, 10);
sprintf(sn, "%d", n);
strcpy(message,sn);
//gets(message);
//Send some data
send(sock , message , strlen(message) , 0);
recv(sock , server_reply , 2000 , 0);
puts("Server reply :");
puts(server_reply);
n++;
}
close(sock);
return 0;
}
You have only a single variable client_sock which is shared between all threads. This means each new accept will replace this variable with the new client socket so that essentially all your threads will work on the same (newest) socket and no thread will handle the previously established sockets.
I am trying to make a TCP Socket Server in C that stores the data that the clients are sending to the server in a struct array. Well, so far, so good. When i am printing the values of the struct, only the last value(key) is stored in all the positions of the struct array!
Why is that? Thanks in advance!
Client Code:
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
char *p;
server.sin_addr.s_addr = inet_addr(argv[1]);
int port = strtol(argv[2], &p, 10);
server.sin_port = htons(port);
server.sin_family = AF_INET;
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
write(sock , argv[3] ,strlen(argv[3])+1); //send the 3rd argument(which is the input key)
close(sock);
return 0;
}
Server Code:
struct key_store
{
char *key;
}store[1024];
int STORED=0;
void handler(int socket_desc)
{
int client_sock;
char client_message[1024];
client_sock = accept(socket_desc, (struct sockaddr *) NULL, NULL);
printf("Connection accepted\n");
while( read(client_sock , client_message , 100) > 0 )
{
store[STORED].key=client_message;
STORED++;
}
close(client_sock);
}
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
server.sin_port = htons( 8888 );
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
printf("Socket created\n");
//Prepare the sockaddr_in structure
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
printf("bind done\n");
//Listen
listen(socket_desc , 5);
int count =0;
while(count < 3)
{
handler(socket_desc);
count++;
}
close(socket_desc);
for (int i=0;i<STORED;i++)
{
printf("KEY --> %s\n",store[i].key); //print the store keys
}
return 0;
}
Input:
./client 127.0.0.1 8888 123456
./client 127.0.0.1 8888 testkey
./client 127.0.0.1 8888 2017
Output:
./server
Socket created
bind done
Connection accepted
Connection accepted
Connection accepted
KEY --> 2017
KEY --> 2017
KEY --> 2017
you are storing a pointer to client_message in your store. Next message will overwrite that buffer. You have to make a copy of the message before you store it
try
put(strdup(client_message));
You have all sorts of other issues, but this will at least move you forward
Am writing an application for a Point of Sale TERMINAL , the manual for the terminal restricts direct MYSQL connection from the terminal, All connections should be done using Sockets. How can I connect to a MYSQL database using C sockets? Below is my working C program that establishes a TCP connection to specified ip and port.
/*
* Create a TCP socket
* #Author Salim Said
* Jan 2 2015 17:00hrs
*/
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_addr.s_addr = inet_addr("74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
//Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected successfully");
return 0;
}
I have a simple server and client C code to do a chatroom for multiclients using threads (pthread library). The problem I've been having is that I can't think a way of making the server write every message that a client sends over the socket into all other clients. I've read other similar posts in here and it was helpless. Please help me I need to do this for school. I'll send both codes right away.
Server.c:
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<pthread.h> //for threading , link with lpthread
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c , *new_sock;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//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)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (new_socket<0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
Client.c
#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");
puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!");
//keep communicating with server
while(1)
{
printf("Enter message: ");
fgets(message, sizeof(message),stdin);
//scanf("%s" , message);
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
//Receive a reply from the server
if( recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}
printf("Server Reply: %s\n", server_reply);
server_reply[0]='\0';
}
close(sock);
return 0;
}
These programs are very simple, the client sends what the user writes in console and the server send the same message back. I just need the server to send the same message to every thread (client) connected (not only the one who sent the original message).
I know this is long for anyone to care, but if you can, I'll be glad to get some help :)
You need a global table of all clients, protected by a mutex. When a new client connects, add them to the global table of clients. When a client disconnects, remove them from the global table.
When a client sends a message, acquire the lock on the global table and traverse it. Send the message to all clients (other than the one that sent the message, if you don't want to echo a message back to its source).
This is a gross oversimplification of how real servers do it. But it should be enough to get you started.