C-code, simple web server (Code OK) - c

I have a problem with my code about web server
#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
int main() {
int create_socket, new_socket;
socklen_t addrlen;
int bufsize = 1024;
char *buffer = malloc(bufsize);
struct sockaddr_in address;
if ((create_socket = socket(AF_INET, SOCK_STREAM, 0)) > 0){
printf("The socket was created\n");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(15000);
if (bind(create_socket, (struct sockaddr *) &address, sizeof(address)) == 0){
printf("Binding Socket\n");
}
while (1) {
if (listen(create_socket, 10) < 0) {
perror("server: listen");
exit(1);
}
if ((new_socket = accept(create_socket, (struct sockaddr *) &address, &addrlen)) < 0) {
perror("server: accept");
exit(1);
}
if (new_socket > 0){
printf("The Client is connected...\n");
}
recv(new_socket, buffer, bufsize, 0);
printf("%s\n", buffer);
write(new_socket, "hello world\n", 12);
close(new_socket);
}
close(create_socket);
return 0;
}
this is a little code to create a web server that at the port 15000 reply with "hello wordl" . Now i would that my server at a request (for example) "http://127.0.0.1:15000/luigi" reply with the text "luigi",that is with the phrase after " / ". Thanks!

After recv function, you will have something like
GET /luigi HTTP/1.1
in buffer.This is the request sent by browser.
Text after GET is the relative url to your base address (127.0.0.1:15000). Now you can parse the buffer and do whatever you want.You can go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html for more details.

To add up to what user3864685 said, you can use 'strtok' function to get the string after "GET /".

Related

Server client program bind function issue

I am implementing server client program where the both the ports user define
in server side user will insert server port number using command line interface
in client side user will insert client port id and then followed by serve port id.
I got stuck for a long time finding out what is wrong with my server client program. The issue is in binding though but I tried whatever possible way to implement it.
Server.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<strings.h>
void error(char *msg){
perror(msg);
exit(1);
}
int main(int argc, char *argv[]){
int sockfd, newsockfd, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if(argc < 2){
fprintf(stderr,"error!!! no port provided\n");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(atoi(argv[1]));
if ((bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
listen(sockfd, 5);
while(1){
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
if(newsockfd < 0){
error("ERROR on accept");
exit(1);
}
printf("New client connected from port no %d and IP %s\n", ntohs(cli_addr.sin_port), inet_ntoa(cli_addr.sin_addr));
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
if(n < 0){
error("ERROR reading from socket");
exit(1);
}
}
printf("Here is the message: %s \n",buffer);
n = write(newsockfd, "I got your message", 18);
if(n < 0){
error("ERROR writing from socket");
exit(1);
}
return (0);
}
Client.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<strings.h>
void error(char *msg){
perror(msg);
exit(1);
}
int main(int argc, char *argv[]){
int sockfd, n;
struct sockaddr_in serv_addr;
char buffer[256];
if(argc < 3){
fprintf(stderr,"usage %s hostname port\n",argv[0]);
exit(0);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
error("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(argv[2]));
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){
error("ERROR connecting");
exit(1);
}
printf("Please enter the message: ");
bzero(buffer, 256);
fgets(buffer, 256, stdin);
n = write(sockfd, buffer, strlen(buffer));
if(n < 0){
error("ERROR writing to socket");
exit(1);
}
bzero(buffer, 256);
n = read(sockfd, buffer, 255);
if(n < 0){
error("ERROR reading from socket");
exit(1);
}
printf("%s\n",buffer);
return (0);
}
Terminal where client is running
Terminal where server is running.
The server never creates a socket. sockfd is an uninitialized, indeterminate value when passed to bind.
Turning up your compiler's warning level may have alerted you to this:
server.c:36:14: warning: ‘sockfd’ may be used uninitialized [-Wmaybe-uninitialized]
36 | if ((bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) != 0) {
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Obtain a valid file descriptor before trying to bind.
if (-1 == (sockfd = socket(...)) {
perror("socket");
return 1;
}
Consider the use of getaddrinfo to establish your sockets. The man page as well as Beej's Guide to Network Programming have various examples.
Additionally, the code that responds to the client
printf("Here is the message: %s \n",buffer);
n = write(newsockfd, "I got your message", 18);
if(n < 0){
error("ERROR writing from socket");
exit(1);
}
is outside of the loop that handles incoming connections.

Send a UDP message from Server to Client

I am experimenting with sending a message from a server to a client using UDP sockets... however, my client is not receiving any messages. Any feedback would be greatly appreciated!
EDIT: maybe I should clarify that the message seems to be sending successfully, however when I run the client it gets stuck on waiting for data... any pointers as to why this is happening would be appreciated!
UDP SERVER
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "127.0.0.1"
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
void die(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen = sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
//create a UDP socket
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
//bind socket to port
if( bind(s , (struct sockaddr*)&si_other, sizeof(si_other) ) == -1)
{
die("bind");
}
else
{
printf ("Success!\n");
}
while(1)
{
printf("Enter message : ");
gets(message);
//send the message
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1)
{
die("sendto()");
}
else
{
printf ("Success!\n");
}
}
close(s);
return 0;
}
UDP CLIENT
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to send data
void die(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s, i, slen=sizeof(si_other), recv_len;
char buf[BUFLEN];
char message[BUFLEN];
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
die("socket");
}
// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
while(1)
{
printf("Waiting for data...");
fflush(stdout);
//try to receive some data, this is a blocking call
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)
{
die("recvfrom()");
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n" , buf);
}
close(s);
return 0;
}
Call bind() from the client and not the server
you need to bind your client, not your server.

printing client ip when server is on same machine

I am writing a simple tcp echo client server code both my client and server code are running on the same machine i did bind two different addresses to client and server but client ip address is not getting printed when connected to server i changed addresses and still i was not able to print address i don't see any mistake in code.Is this my os issue or am i making some mistake.
my server code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define MAX_CLIENTS 10
#define MAX_DATA 1024
int main(int argc, char *argv[]){
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof(struct sockaddr_in);
int data_len;
char data[MAX_DATA+1];
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("server socket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
inet_aton(argv[2],&server.sin_addr.s_addr);
bzero(&server.sin_zero,0);
if(bind(sock, (struct sockaddr *)&server,sockaddr_len) == ERROR){
perror("bind");
exit(-1);
}
if(listen(sock, MAX_CLIENTS) == ERROR){
perror("listen");
exit(-1);
}
while(1){
if((new = accept(sock,(struct sockaddr *)&client,&sockaddr_len)) == ERROR){
perror("accept");
exit(-1);
}
//ip not getting printed
printf("New client connected from port no %d IP %s\n",ntohs(client.sin_port),inet_ntoa(client.sin_addr.s_addr));
data_len = 1;
while(data_len){
data_len = recv(new,data,MAX_DATA,0);
if(data_len){
send(new, data, data_len,0);
data[data_len] = '\0';
printf("Sent message: %s", data);
}
}
printf("Client disconnected\n");
close(new);
}
}
my client code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define BUFFER 1024
int main(int argc, char *argv[]){
struct sockaddr_in remote_server,client;
int sock,len;
char input[BUFFER];
char output[BUFFER+1];
client.sin_family = AF_INET;
client.sin_port = htons(3000);
inet_aton("127.0.2.8",&client.sin_addr.s_addr);
bzero(&client.sin_zero,0);
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("socket");
exit(-1);
}
int size = sizeof(struct sockaddr_in);
if(bind(sock, (struct sockaddr *)&client,size) == ERROR){
perror("bind");
exit(-1);
}
remote_server.sin_family = AF_INET;
remote_server.sin_port = htons(atoi(argv[2]));
remote_server.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&remote_server.sin_zero , 0);
if((connect(sock ,(struct sockaddr *)&remote_server , sizeof(struct sockaddr_in))) == ERROR){
perror("connect");
exit(-1);
}
while(1){
fgets(input, BUFFER, stdin);
send(sock, input, strlen(input) , 0);
len = recv(sock,output,BUFFER,0);
output[len] = '\0';
printf("%s\n",output);
}
close(sock);
}
This is the output:
New client connected from port no 3000 and IP
First of all you need two more includes in client as well as server
#include<arpa/inet.h> // for inet_aton(), inet_addr() and inet_ntoa()
#include<unistd.h> //for close()
Secondly,
The function declaration for inet_aton() and inet_ntoa() are respectively:
int inet_aton(const char *cp, struct in_addr *inp);
and
char *inet_ntoa(struct in_addr in);
So, You must pass the entire structure i.e xyzaddr.sin_addr instead of xyzaddr.sin_addr.s_addr(which is an int)
Hence make these changes as well:
In server:
inet_aton(argv[2],&server.sin_addr.s_addr); -> inet_aton(argv[2],&server.sin_addr);
inet_ntoa(client.sin_addr.s_addr) -> inet_ntoa(client.sin_addr)
In client:
inet_aton("127.0.2.8",&client.sin_addr.s_addr); -> inet_aton("127.0.2.8",&client.sin_addr);

If i want to write multiple requests one by one from client to server, what should I do?

For instance, there are several requests in a file, and I read them then send to server line by line by using write function. However, there is only one response from server, and I cannot read the whole requests to server. Is there anyone who can help me to figure out this problem. Thank you so much!
There is server code:
<pre> <code>
int main(int argc, char *argv[]){
int sockfd, newsockfd, n;
unsigned int clientLen;
char bufferSK[256];
struct sockaddr_in serv_addr,cli_addr;
FILE *fp = NULL;
//create an endpoint for bind, listen and accept.
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd < 0) {
printf("Failed to create socket for server!\n");
}
bzero((char *)&serv_addr, sizeof(serv_addr));
//set the address of server.
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port_number);
//bind the port with server address
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("Error on bind!\n");
}
listen(sockfd,port_number);
printf("\nI am listening for connection\n");
clientLen = sizeof(cli_addr);
//using accept function to accept the connection from client
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clientLen);
if (newsockfd < 0) {
printf("Error on accept!\n");
}
printf("\nI have accepted your connection\n");
bzero(bufferSK,256);
n = read (newsockfd, bufferSK,255);
if (n < 0) {
printf("Error reading message from socket\n");
}
printf("\nThe message from client is: %s",bufferSK);
n = write(newsockfd, "SERVER: I got your message!\n", 27);
if (n < 0) {
printf("Error writing to socket\n");
}
close(newsockfd);
close(sockfd);
return 0;
}
there is client code:
<pre> <code>
FILE *fp_queue;
int main(int argc, char *argv[]){
int sockfd, server_port_number, n, connectRes;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
//Three parameters must be provided.
if(argc != 4){
fprintf(stderr, "Usage: %s server_host_name server_port_number file_path\n",argv[0]);
exit(0);
}
server_port_number = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
//create socket for client.
if (sockfd < 0) {
printf("Failed to create socket for client\n");
exit(0);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
printf("Oops! There is no such host!\n");
exit(0);
}
//set the attributes of server as zeros.
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
//copy the server address from serv_addr.sin_addr.s_addr to server->h_adddr.
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(server_port_number);
connectRes = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (connectRes < 0) {
printf("Error connection\n");
exit(0);
}
printf("connect successfully\n");
fp_queue = fopen(argv[3], "r");
if (fp_queue == NULL) {
printf("Failed open client file %s\n", argv[3]);
exit(1);
}
bzero(buffer, 256);
while ((fgets(buffer,sizeof(buffer),fp_queue)) != NULL) {
buffer[strlen(buffer) - 1] = '\0';
printf("buffer is %s\n", buffer);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0) {
printf("Error write to socket\n");
}
bzero(cliBuffer, 256);
n = read(sockfd, buffer, 256);
if (n <0) {
printf("Error read from socket\n");
}
printf("%s\n", buffer);
}
close(sockfd);
return 0;
}
There are at least 2 design issues in the code.
The server code receives one request, sends a response and then server terminates. If you want to process more requests over one connection then the server code must contain a loop like a client has. The server code should contain something like
while ((n = read (newsockfd, bufferSK, 255) > 0) {
printf("\nThe message from client is: %s",bufferSK);
n = write(newsockfd, "SERVER: I got your message!\n", 27);
if (n < 0) {
printf("Error writing to socket\n");
break;
}
}
close(newsockfd);
The next problem is that TCP is a stream oriented protocol and your code does not consider that. The stream orientation means that protocol does not keep message boundaries. When a sender calls write("a"); write("b") the receiver may get characters in two separate reads or it may receive 2 characters in one read. To overcome the problem the peers must define some protocol how to determine message boundaries. Usually client sends a message length at begin of message or a control character is used as message boundary or messages have fixed length.

Connect a client to a server?

I have a simple question for you. I'm trying to make a simple client-server program. I want to connect the client to the server but I get the following error: Can't connect to the server. I'm new with this and this is why I can;t figure out what the problem is. Please give me some hints. Here is my client/server code:
Client:
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>
#include<stdint.h>
int main(){
int socketc;
int connectnr;
int c;
struct sockaddr_in server;
char buffer[256];
socketc = socket(PF_INET, SOCK_STREAM, 0);
if(socketc < 0){
fprintf(stderr, "Error: Can't create client socket.\n");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(4321);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
connectnr = connect(c, (struct sockaddr *) & server, sizeof(struct sockaddr_in));
if(connectnr < 0){
printf("connectnr %d: \n", connectnr);
fprintf(stderr, "Error: Can't connect to the server.\n");
return 1;
}
close(c);
}
Server:
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>
#include<stdint.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
int c;
int main(){
int connsocket;
int bindcod;
int l;
struct sockaddr_in client, server;
connsocket = socket(PF_INET, SOCK_STREAM, 0);
if(connsocket < 0){
fprintf(stderr, "Error: Can't create the server socket.\n");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(4321);
server.sin_addr.s_addr = INADDR_ANY;
bindcod = bind(connsocket, (struct sockaddr *) &server, sizeof(struct sockaddr_in));
if(bindcod < 0){
fprintf(stderr, "Error: Con't establish the bind. Port is already used.\n");
return 1;
}
listen(connsocket, 5);
while(1){
memset(&client, 0, sizeof(client));
l = sizeof(client);
printf("Waiting for the client to connect,\n");
c = accept(connsocket, (struct sockaddr *) &client, &l);
printf("New client connected with address %s and port %d.\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
}
}
You are giving wrong socket to connect function.
Replace
connect(c, (struct sockaddr *) & server, sizeof(struct sockaddr_in));
with
connect(socketc , (struct sockaddr *) & server, sizeof(struct sockaddr_in));

Resources