I'm trying to access the website https://www.000webhost.com with C sockets:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
struct sockaddr_in servaddr;
struct hostent *hp;
int sock_id;
char message[1024*1024];
char request[] = "GET / HTTP/1.1\n" "From: ...\n";
//get a socket
if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr,"Couldn't get a socket.\n");
exit(EXIT_FAILURE);
}else {
fprintf(stderr,"Got a socket.\n");
}
memset(&servaddr,0,sizeof(servaddr));
//get address
if((hp = gethostbyname("000webhost.com")) == NULL) {
fprintf(stderr,"Couldn't get an address.\n");
exit(EXIT_FAILURE);
}else {
fprintf(stderr,"Got an address.\n");
}
memcpy((char *)&servaddr.sin_addr.s_addr, (char *)hp->h_addr, hp->h_length);
//port number and type
servaddr.sin_port = htons(80);
servaddr.sin_family = AF_INET;
//connect
if(connect(sock_id, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
fprintf(stderr, "Couldn't connect.\n");
}else {
fprintf(stderr,"Got a connection.\n");
}
//request
write(sock_id,request,strlen(request));
//response
read(sock_id,message,1024*1024);
fprintf(stdout,"%s",message);
return 0;
}
If I change the request[] array from "GET / HTTP/1.1\n" "From: ...\n" to "GET / HTTP/1.1\n" "Host: https://www.000webhost.com" "From: ...\n" (therefore removing the direct-IP adress from the request), I still get the error Error 1003. Direct IP access not allowed. Is there some other part of the request that I need to modify? What else do I need to do?
Your request is malformed:
Each line needs to be terminated by \r\n, not just \n. (Some web servers will let you get away with \n, but I have no idea whether that'll work on 000webhost.)
Every header needs a \r\n after it. The modified code you mention in the last paragraph is missing a \r\n at the end of the Host header.
The Host header needs to just be a hostname (e.g, "Host: example.com"). Don't include http://.
Related
Spending way too much time trying to figure out why inet_ntop is always returning the same IP address of 2.0.19.86 inside of my barebones C UDP socket program.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define SERVERPORT "4950" // the port users will be connecting to
int main(int argc, char *argv[])
{
int sock;
struct addrinfo addr_type, *server_info, *p;
int err;
int numbytes;
if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}
//Specify type of response we want to git
memset(&addr_type, 0, sizeof addr_type);
addr_type.ai_family = AF_INET; // set to AF_INET to use IPv4
addr_type.ai_socktype = SOCK_DGRAM;
//Get the address info (like IP address) and store in server_info struct
if ((err = getaddrinfo(argv[1], SERVERPORT, &addr_type, &server_info)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
return 1;
}
// There might be multiple IP addresses...loop through and use the first one that works
for(p = server_info; p != NULL; p = p->ai_next) {
if ((sock = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("Error when creating socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "Client failed to create socket\n");
return 2;
}
char s[INET_ADDRSTRLEN];
inet_ntop(AF_INET,(struct sockaddr_in *)p->ai_addr,s, sizeof s);
printf("sending to %s....\n",s);
if ((numbytes = sendto(sock, argv[2], strlen(argv[2]), 0,
p->ai_addr, p->ai_addrlen)) == -1) {
perror("Error sending message");
exit(1);
}
printf("client sent %d bytes to %s\n", numbytes, argv[1]);
freeaddrinfo(server_info);
close(sock);
return 0;
}
The lines I am particularly stuck on is:
char s[INET_ADDRSTRLEN];
inet_ntop(AF_INET,(struct sockaddr_in *)p->ai_addr,s, sizeof s);
printf("sending to %s....\n",s);
For example I run the program with ./client www.google.com hello and get the following:
sending to 2.0.19.86....
client sent 5 bytes to www.google.com
I run the program again with ./client localhost hello and inet_ntop still returns the same IP.
sending to 2.0.19.86....
client sent 5 bytes to localhost
No errors are being thrown when I am creating the socket, and the message sends successfully when I send it to the receiving program over localhost, why is inet_ntop still outputting this weird address?
In your call to inet_ntop:
inet_ntop(AF_INET,(struct sockaddr_in *)p->ai_addr,s, sizeof s);
You're not passing in the correct structure. When AF_INET is passed as the first argument, the second argument should have type struct in_addr *, not struct sockaddr_in *.
You need to call out the sin_addr member which is of this type.
inet_ntop(AF_INET, &((struct sockaddr_in *)p->ai_addr)->sin_addr, s, sizeof s);
I need simple HTTP client on Raspberry PI zero with Raspbian. I used few example codes, but when i send about 7 requests then i can download just page with this error:
503 Service temporarily unavailable
There is no available fastcgi process to fullfill your request.
One of used codes:
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <unistd.h>
#define SA struct sockaddr
#define MAXLINE 4096
#define MAXSUB 200
ssize_t process_http(int sockfd, char *host, char *page)
{
ssize_t n;
snprintf(sendline, MAXSUB,
"GET %s\r\n"
"Host: %s\r\n"
"Connection: close\n"
"\n", page, host);
write(sockfd, sendline, strlen(sendline));
while ((n = read(sockfd, recvline, MAXLINE)) > 0)
{
recvline[n] = '\0';
}
printf("%s", recvline);
return n;
}
and in main is this:
int sockfd;
struct sockaddr_in servaddr;
char **pptr;
char *hname = "plankter.cz";
char *page = "http://plankter.cz/iot/list.json";
char str[50];
struct hostent *hptr;
if ((hptr = gethostbyname(hname)) == NULL) {
fprintf(stderr, " gethostbyname error for host: %s: %s",
hname, hstrerror(h_errno));
exit(1);
}
printf("hostname: %s\n", hptr->h_name);
if (hptr->h_addrtype == AF_INET
&& (pptr = hptr->h_addr_list) != NULL) {
printf("address: %s\n",
inet_ntop(hptr->h_addrtype, *pptr, str,
sizeof(str)));
} else {
fprintf(stderr, "Error call inet_ntop \n");
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
inet_pton(AF_INET, str, &servaddr.sin_addr);
connect(sockfd, (SA *) & servaddr, sizeof(servaddr));
process_http(sockfd, hname, page);
close(sockfd);
In this example i download json, but when i read php or txt, i have same problem. I tried some another example codes using sockets, example with happyhttp library and all give me same result after 7 requests. I think it doesn't close connection. I need to send http request and recieve data, and i need to do it few times in minute.
Thanks for all ideas.
You provide a full URI to the GET field:
char *page = "http://plankter.cz/iot/list.json";
...
snprintf(sendline, MAXSUB,
"GET %s\r\n"
"Host: %s\r\n"
"Connection: close\n"
"\n", page, host);
You should not include protocol and host name.
Try this instead:
char *page = "/iot/list.json";
I have made one server and one client communicating through UDP sockets. The work that I am trying to do is that client will pass a string in the arguments and that string will be send to the server using UDP sockets. After receiving the string server will again echo(send) the string back to the client.Below are the codes for both:
code for echoClient.c :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXLINE 4096
int main(int argc, char const *argv[])
{
int sockfd;
struct sockaddr_in servAddr;
char sendLine[MAXLINE],recvLine[MAXLINE];
if(argc!=3)
{
printf("echoClient <Ip addr. of the server> <String to be echoed> \n");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
printf("Error in creating the socket\n");
exit(2);
}
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(6565); // setting up the port
servAddr.sin_addr.s_addr = inet_addr(argv[1]); // using the given ip address of the server
printf("%s\n", argv[2]);
if((sendto(sockfd,(const char *)argv[2],strlen(argv[2]), MSG_CONFIRM,(struct sockaddr *) &servAddr, sizeof(servAddr))!=-1))
{
printf("data is sent to the server\n");
}
else
{
printf("can't send the data to the server\n");
exit(3);
}
int n = recvfrom(sockfd,(char * ) recvLine,MAXLINE,0,(struct sockaddr * )&servAddr,sizeof(servAddr));
if(n==-1)
{
printf("Can't receive the data from the server\n");
exit(4);
}
recvLine[n] = '\0'; // to terminate the received string
printf("%s\n",recvLine);
return 0;
}
code for echoServer.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define MAXLINE 4096
int main(int argc, char const *argv[])
{
int sockfd;
struct sockaddr_in servAddr,clientAddr;
char sendLine[MAXLINE],recvLine[MAXLINE];
if(argc!=1)
{
printf("echoServer\n");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
printf("Error in creating the socket\n");
exit(2);
}
memset(&servAddr,0,sizeof(servAddr));
memset(&clientAddr,0,sizeof(clientAddr));
// filling the details of the server ip and port
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(6565);
servAddr.sin_addr.s_addr = INADDR_ANY; // using the given ip address of the server
if(bind(sockfd,(struct sockaddr * )&servAddr,sizeof(servAddr))<0)
{
printf("Binding of the socket failed\n");
exit(1);
}
printf("Server is Up... Waiting for the client...\n");
int len;
int n = recvfrom(sockfd,(char *) recvLine,MAXLINE,MSG_WAITALL,(struct sockaddr * )&clientAddr,&len);
if(n==-1)
{
printf("can't get the message from the client\n");
exit(2);
}
recvLine[n] = '\0';
printf("Message received from the client is %s\n",recvLine);
if(sendto(sockfd,(char *) recvLine,n,MSG_CONFIRM,(struct sockaddr *)&clientAddr,len)<0)
{
printf("can't send the message to the client\n");
exit(3);
}
return 0;
}
Now the actual problen is that when I am executing the above codes client is able to send the string to the server but server is unable to send the string back to the client.Server gives the error can't send the message to the client.
I am not able to figure out the error which is stopping the server to send the message to the client.Please help me with this.
I am running the echoClient.c with the command :
./a.out 127.0.0.1 hellofromclientside
In the server, you overlooked that the argument len to recvfrom() is a value-result argument, which before the call you have to initialize to the size of the clientAddr in order to get this address, so change
int len;
to
int len = sizeof clientAddr;
Similarly in the client, change
int n = recvfrom(sockfd,(char * ) recvLine,MAXLINE,0,(struct sockaddr * )&servAddr,sizeof(servAddr));
to
int len = sizeof servAddr;
int n = recvfrom(sockfd, recvLine, MAXLINE, 0, (struct sockaddr *)&servAddr, &len);
I am trying to build a HTTP request using sockets in c.
So, in order to navigate the socket to the correct site ip.
I need to get the site ip.
I have managed to get the host ip but that not always work.
The following code gets the host ip:
host = gethostbyname(host_name);
if (host != NULL) {
memcpy(&inp, host->h_addr_list[0], host->h_length);
sprintf(ip, "%s", inet_ntoa(inp));
}
But that not always work, for example if I want to send the socket to stackoverflow.com and get his HTML content.I used this code and the output was: "198.252.206.16".
And if you enter that ip you can see that it is a wrong ip,so what can I do?
Please help.
P.S that this all my code:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
#include <assert.h>
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: %s domain_name\nE.g. %s www.yahoo.com/lalal.html\n", argv[0], argv[0]);
return(0);
}
struct protoent *pr;
struct in_addr inp;
int x = 1;
int ret;
char buf[4192];
char ip[16];
struct hostent *host;
int sock, bytes_recieved;
struct sockaddr_in server_addr;
char url[strlen(argv[1])];
strcpy(url,argv[1]);
char *index_page = strstr(argv[1], "/");
char *host_name = strtok(url,"/");
char message[4000];
sprintf(message,"GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",index_page,host_name);
printf("%s",message);
host = gethostbyname(host_name);
if (host != NULL) {
memcpy(&inp, host->h_addr_list[0], host->h_length);
sprintf(ip, "%s", inet_ntoa(inp));
}
else {
printf("ERROR - Host ip was not found.\n\n");
exit(1);
}
printf("%s\n",ip);
pr = getprotobyname("tcp");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket");
exit(1);
}
printf("%s\n",message);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
perror("Connect");
exit(1);
}
write(sock, message, strlen(message));
while ((ret = read(sock, buf, 4192)) != 0) {
buf[ret]='\0';
fwrite(buf, ret, sizeof(char), stdout);
x++;
}
if (close(sock) == -1)
printf("Close socket error\n");
return 0;
}
StackExchange hosts multiple sites on the same server. 198.252.206.16 is the IP address of that server, and that is the correct IP address you need to connect your socket to.
When requesting an HTTP resource from a site that resides on a shared server, you must provide an HTTP Host header to specify the site's hostname so the server knows which site you are trying to access.
For example, if you go to http://198.252.206.16, the request would look like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: 198.252.206.16
...
If you go to http://www.stackoverflow.com, the request looks like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: www.stackoverflow.com
...
If you go to http://www.stackexchange.com, the request looks like this:
(connect to 198.252.206.16)
GET / HTTP 1.1
Host: www.stackexchange.com
...
Notice that they all connect to the same IP address.
There is no site associated with the 198.252.206.16 host, which is why you get the error message.
The Host header is required for all HTTP 1.1 requests, and is optional for HTTP 1.0 requests (but an HTTP 1.0 request will fail in this situation if the Host header is missing). It was designed specifically to support multiple sites on a shared server.
I'm trying to write a TCP client that fetches HTML. The program would accept a website from user and print out the content. Right now my code only fetches a HTML back saying error 408 request timeout error page.
Where is the problem?
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char* argv[])
{
char *domain = argv[1];
char *path = strchr(domain, '/');
*path++ = '\0';
//printf("host: %s; path: %s\n", domain, path);
int sock, bytes_recieved;
char send_data[1024],recv_data[9999];
struct sockaddr_in server_addr;
struct hostent *he;
he = gethostbyname(domain);
if (he == NULL){
herror("gethostbyname");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0))== -1){
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(server_addr.sin_zero),8);
if (connect(sock, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1){
perror("Connect");
exit(1);
}
snprintf(send_data, sizeof(send_data), "GET /%s HTTP/1.1\r\n Host: %s\r\n \r\n \r\n", path, domain);
//printf("%s\n", send_data);
send(sock, send_data, strlen(send_data), 0);
printf("Data sended.\n");
bytes_recieved = recv(sock, recv_data, 9999, 0);
recv_data[bytes_recieved] = '\0';
close(sock);
printf("Data reveieved.\n");
printf("%s\n", recv_data);
return 0;
}
For example, right now if I'm trying to run ./client www.facebook.com It would return a HTML page says error occurs
Check your HTTP Get request, it should be
GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n