TCP IP socket communication in C. During the client exit, intimating server? - c

I am checking the communication between 2 entities (A and B) for their presence. A is a server and B is a client. When the server is up and running, it waits for connections and when B starts, it sends a message "Available" every one second. Now, the problem is, when I terminate the B program( ctrl+c or press the close button of the terminal), the server A does not recognise and still continues its operation. I would like for it to display message like "B is no more available" or "communicating partner is off". I understand TCP would be a best fit for the connection oriented communication. Please suggest me the changes to incorporate the display message on server A, when B is closed.
PS: amateur in socket programming
EDIT1: Managed to display the Message. However, since the server is designed to listen to many connections, I would like to make it accept the connections and not end the loop. Any guidance here would be useful.
SERVER(A) TCP SERVER
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main( int argc, char *argv[] ) {
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
// create socket and get file descriptor
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
clilen = sizeof(cli_addr);
// bind the host address using bind() call
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
perror("ERROR on binding\n");
exit(1);
}
// start listening for the clients,
// here process will go in sleep mode and will wait for the incoming connection
listen(sockfd, 5);
// accept actual connection from the client
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
// inside this while loop, implemented communication with read/write or send/recv function
//printf("start");
while (1) {
bzero(buffer,256);
n = read(newsockfd, buffer, 255);
if (n < 0){
perror("ERROR in reading from socket");
exit(1);
}
if (n == 0){
perror("Client has abruptly ended\n");
close(sockfd);
exit(1);
}
printf("client said: %s \n", buffer);
n = write(newsockfd, buffer, strlen(buffer));
if (n < 0){
perror("ERROR in writing to socket");
exit(1);
}
// escape this loop, if the client sends message "quit"
// if (!bcmp(buffer, "quit", 4))
// break;
}
return 0;
}
CLIENT(B) TCP CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
portno = 5001;
// create socket and get file descriptor
sockfd = socket(AF_INET, SOCK_STREAM, 0);
server = gethostbyname("127.0.0.1");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
// connect to server with server address which is set above (serv_addr)
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR while connecting");
exit(1);
}
// inside this while loop, implement communicating with read/write or send/recv function
while (1) {
strcpy(buffer,"Available");
n = write(sockfd,buffer,strlen(buffer));
if (n < 0){
perror("ERROR while writing to socket");
exit(1);
}
bzero(buffer,256);
n = read(sockfd, buffer, 255);
if (n < 0){
perror("ERROR while reading from socket");
exit(1);
}
printf("server replied: %s \n", buffer);
// escape this loop, if the server sends message "quit"
//if (!bcmp(buffer, "quit", 4))
// break;
sleep(1);
}
return 0;
}
Please anybody tell me how to handle that issue?

When the client closes the TCP connection, the server's call to read(newsockfd) will return 0 to indicate that the connection has closed. At that point, the server should close(newsockfd), print your "Client has gone away message", and not use newsockfd anymore (i.e. either the server program should exit, or, more usefully, it should just break out of its while(1)-loop and go back to calling accept() again, so that the next time a client runs it too can connect to the server)

Related

Persistent Connection in C socket programming

I have written a client code to create a socket and send a request to the client and as HTTP 1.1 uses Connection:Alive by default still the connection closes.How can i create a persistent connection such that the server listens to every request until the connection is closed.The client side code is:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(char *msg){
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n,i;
int Max_Requests;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
Max_Requests=atoi(argv[3]);
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
i=0;
while(i<Max_Requests){
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
i++;
}
return 0;
}
The problem is your use of fgets to read input from the user to form the request.
The problem with it is how you use it, namely to read a single line that you send to the server as the request. You then promptly go to the read call and wait for the response, without having sent the full request and its headers.
That will lead the server to time-out and close the connection, since it haven't received a full request.

Unexpected output in IPC using sockets

I am trying to write a server that can handle at most 5 concurrent clients.
Whenever a client gets successfully connected to the server & the number of clients is less than or equal to 5, the server sends a welcome message, generates a 5 digit unique random number for identifying that client, sends this number to the client and prints this number in the console.If the number of clients tends to be greater than 5, then for each new request, it just sends a message "Connection Limit Exceeded" to the client & closes the connection.
Client just prints the messages sent by the server.
The problem I'm facing is that, the random number is not being propagated properly to the client.Few times the client prints the same number as generated by the server but few times the client just prints 0(as the variable storing incoming value of that random number is initialized to 0).
What could be the reason behind this?
Here are the codes for client and server:
server:
/* A simple server in the internet domain using TCP
The port number is passed as an argument
This version runs forever, forking off a separate
process for each connection
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <stdlib.h>
void dostuff(int); /* function prototype */
void write_once (int sock);
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, pid, count = 0;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
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)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
pid = fork();
count++;
if (pid < 0)
error("ERROR on fork");
if (pid == 0 && count <=5 ) {
close(sockfd);
dostuff(newsockfd);
exit(0);
}
if (pid == 0 && count >= 5 ) {
close(sockfd);
write_once(newsockfd);
exit(0);
}
else close(newsockfd);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
/******** DOSTUFF() *********************
There is a separate instance of this function
for each connection. It handles all communication
once a connnection has been established.
*****************************************/
void dostuff (int sock)
{
int n;
char buffer[256];
bzero(buffer,256);
n = write(sock,"Welcome\n",8);
if (n < 0) error("ERROR writing to socket");
srand((unsigned int)time(NULL));
int r = rand() % 90000 + 10000;
int converted_r = htonl(r);
n = write(sock, &converted_r, sizeof(converted_r));
if (n < 0) error("ERROR writing to socket");
printf("%d\n", r);
}
void write_once (int sock)
{
int n;
char buffer[256];
bzero(buffer,256);
n = write(sock,"Connection Limit Exceeded!!",28);
if (n < 0) error("ERROR writing to socket");
}
client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
int received_int = 0;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
n = read(sockfd, &received_int, sizeof(received_int));
if (n < 0)
error("ERROR reading from socket");
printf("%d\n", ntohl(received_int));
close(sockfd);
return 0;
}
Reference
The issue is that TCP is a stream oriented protocol, and not packet oriented. So it may happen that
The first read() of the client reads what the first write() of the server sent ("Welcome")
The second read() of the client reads what the second write() of the server sent (Your number)
This is what you expect and what sometimes happens.
However, it might also be that the client reads the data of both writes of the server at once! This usually happens when
either the server aggregated the two writes to a single tcp-packet
or the client reads the data after both tcp segments with data arrived
You cannot make sure what happens and cannot rely on any specific behaviour.
How to fix this depends solely on your protocol. If the first message is always "Welcome\n", then try to read only 8 bytes first. If you happen to read n < 8 bytes, you have to retry and read 8-n bytes to get the rest of the message. Subsequently read sizeof(received_int) bytes, also watching for the real number of bytes received.
If the message is of variable length you will have to use some kind of framing like a preceding length-byte or something like that.

How to convert a simple client server TCP program into non blocking one

Hi I was reading about non-blocking calls using select() from Beej's guide, but I'm still confused as to how to change my simple client-server code to one that is non blocking. Could anyone tell me what changes do I need to make in the server code as well as the client code for that?
Here's the server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t 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);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
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)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}
Here is the client code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
The way select(2) makes things non-blocking is by waiting for I/O to become possible without blocking (e.g., when new data is available). When using select(), you wouldn't normally have to put the monitored descriptors into non-blocking mode (with e.g. SOCK_NONBLOCK), so in a sense select() is specifically about avoiding having to use non-blocking I/O.
select() is used to wait for events on multiple descriptors at once. An event here is something that would make it possible to read(2) from or (depending on how you use select()) write(2) to the descriptor without blocking.
As an example, you could use select() to simultaneously wait for new client connections and data from already connected clients in your server (assuming you extend it to handle multiple clients). To do this, you would use select() to monitor both sockfd and any descriptors you get back from accept(2). Without select(), you would have to use some form of non-blocking I/O (or separate threads) instead to avoid getting stuck in e.g. the accept() until a new client connects, which would prevent you from seeing data from other clients in the meantime. That would be both messier to implement and also less efficient than sleeping in a single location.
select() doesn't do any I/O by itself. It only notifies you when I/O becomes possible without blocking. You pass it a set of descriptors, and it tells you whenever I/O becomes possible on any of them. (And also tells you which descriptors it's possible on.)
In addition to waiting for data on sockets, you could use select() to wait for e.g. user input on stdin at the same time. There are many different types of descriptors that can be select()ed on.

Unable to connect to a socket on a different machine over the same network

I tried running both of the following server and client programs on the same computer. I ran server with port 5100. Then I ran client with arguments localhost 5100. It works then. But when I ran server on one computer and client on another computer over the same network, client keeps saying ERROR connecting: Connection timed out. When I ran client I sent in the private IP of the server machine and the port number. I tried to ping the server from the client machine and all the packets were transmitted and received so I know that both computers can communicate wih each other. All of the following code was obtained from www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html . Any help/suggestions would be much appreciated. Thank You.
This is client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
This is server.c
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, 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);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
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)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
return 0;
}
Just to complement the previous answer, if your iptables are blocking data via chain polices, make sure they are in "ACCEPT" mode:
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
You may try the same for any other chains you have on the both machines.
The above code is working fine across different machines. Probably the issue you are facing have to do with your iptables or firewall. See the available ports in the server and client side using iptables -L and use one of the port which is common in both client and server side.
For example, iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpts:21100:21299
ACCEPT tcp -- anywhere anywhere tcp dpts:21100:21299
ACCEPT udp -- anywhere anywhere udp dpt:8092
ACCEPT udp -- anywhere anywhere udp dpt:8091
ACCEPT tcp -- anywhere anywhere tcp dpt:diameter
ACCEPT tcp -- anywhere anywhere tcp dpt:irdmi
ACCEPT tcp -- anywhere anywhere tcp dpt:mysql
ACCEPT tcp -- anywhere anywhere tcp dpt:8092
Here you can see that port 8092 is free. So when use this, it will work. Or flush your iptables using iptables -F on both machines and try again. There's nothing wrong in the code.

C sockets: forward a request to port 80 and read response

I have the following code (I'm working from code at http://www.linuxhowtos.org/C_C++/socket.htm) which I'm trying to turn into a proxy server:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void dostuff(int); /* function prototype */
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
//setup proxy:
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr,"***ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("***ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
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)
error("***ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("***ERROR on accept");
pid = fork();
if (pid < 0)
error("***ERROR on fork");
if (pid == 0) {
close(sockfd);
dostuff(newsockfd);
exit(0);
}
else close(newsockfd);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
/******** DOSTUFF() *********************
There is a separate instance of this function
for each connection. It handles all communication
once a connnection has been established.
*****************************************/
void dostuff (int sock)
{
int n;
char buffer[256];
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0){
error("***ERROR reading from socket");
}
//printf("Here is the message: %s\n",buffer);
/*
***Forward message to port 80 and read response here
*/
n = write(sock,"I got your message",18);
if (n < 0) error("***ERROR writing to socket");
}
In the function "dostuff" I want to write 'buffer' to port 80, read the response and write this response back over port 20000 (argv[1]).
At the moment, when I set my browser's proxy to 172.16.1.218:20000, all I get is "I got your message". I want to change this to the response from the webpage!
Any pointers in the right direction greatly appreciated.
Here's what I've tried sofar (replace multi-line comment "Forward message to port 80 and read response here" with this code):
int sockfdi, portnoi, ni;
struct sockaddr_in serv_addri;
struct hostent *serveri;
portnoi =80;
sockfdi = socket(AF_INET, SOCK_STREAM, 0);
if (sockfdi < 0){
error("***ERROR opening socket");
}
serveri = gethostbyname("172.16.1.218");
if (serveri == NULL){
fprintf(stderr,"***ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addri, sizeof(serv_addri));
serv_addri.sin_family = AF_INET;
bcopy((char *)serveri->h_addr, (char *)&serv_addri.sin_addr.s_addr, serveri->h_length);
serv_addri.sin_port = htons(portnoi);
if (connect(sockfdi,(struct sockaddr *) &serv_addri,sizeof(serv_addri)) < 0){
error("***ERROR connecting");
}
printf("Please enter the message: ");
bzero(buffer,256);
But every time I try to connect via my webbrowser, the server echos: "***ERROR connecting: Connection refused"
Many thanks in advance,
This is a non-trivial task you set out to do. Currently, you're missing three things, an easy one and two difficult ones:
You have to open a network connection to the server you want to forward the call to (rather easy, see socket() and connect()).
You'll then have a duplex connection, that is two concurrent streams of data, one going from the client to the forwarded server and one from the forwarded server to the client. In order to cope with this concurrency, you either need two threads with blocking I/O or some sort of non-blocking I/O (see select() or AIO).
If you forward an HTTP request without changes to another server, you'll likely end up with invalid server names and IP addresses in the request. The request will then be rejected. So you'll need to parse the HTTP header, do some replacements and forward the modified HTTP request.

Resources