I got an program that creates an socket for given port no .. i need to display an hello world text while it is accessed in browser say if the port is 8080 while visiting i need to display an hello world text using c++
prog:
#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;
}
Web Browsers talk HTTP when you start a URL with http:// so your server will need to talk HTTP as well.
The Browser will typically send
GET / HTTP/1.1
Host: my_website
Header1: blah blah
Header2: blah blah
The request ends with Carriage return(CR) linefeed(LN), CR LN
You will then need to create your response which will be something like
HTTP/1.1 200 OK
Content-Length: 11
Content-Type: text/plain
Hello World
With the blank line all new line having CRLN
As others have mentioned you will probably want to do something to ensure your read does not block your server.
Your code won't do that. Its going to block at the 'read(newsockfd..' until it gets input which the browser isn't going to send.
It looks like you have copied some socket server sample. It would probably be fine with the corresponding client sample but not with a browser.
If the page in the browser should display "Hello World!" then just write that instead of "I got your message".
Your example works.
Compile & run with
g++ socket.cpp
./a.out 8080
Point your browser at it:
firefox http://localhost:8080
The browser should say:I got your message
Note: You got this example from linuxhowtos.org.
Pointing people to that might also help them deduce issues.
Related
i am setting up a web server in c++. I need to return from server a feature vector in the form of vector. I see that the socket doesn't allow such object to pass through directly, but need to serialize it. I am trying to serialize it by converting my vector result to a char* a. but when i do curl request, it still get back nothing.
Would anyone let me know the trick here?
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
// server.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <vector>
#include <iostream>
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);
while (1 == 1) {
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("before result: %s\n",buffer);
std::vector<float> fv;
fv.push_back(7);
fv.push_back(8);
char* result = reinterpret_cast<char*>(&fv);
send(newsockfd, result, sizeof(result), 0);
//n = write(newsockfd,"I got your message",18);
//if (n < 0) error("ERROR writing to socket");
printf("message sent. \n");
close(newsockfd);
//close(sockfd);
}
return 0;
}
To compile the code:
g++ -o server server.cpp
And run:
./server 8080
For curl request:
curl http://localhost:8080
And i get:
alliey:socket alliey$ curl http://localhost:8080
`N�.
How should i interpret the response?
i figure it out, by simply send raw data:
send(newsockfd, result.data(), sizeof(result[0])*result.size(), 0);
On the client side, i used python struck.unpack to receive the result. It works pretty well.
But still thanks for all the tips above!
Here is my code for a node.js TCP server hosted on both Heroku and AppFog. My client was written in C and it simply sends a message to the server and get the response. When I host the server on local, they work fine. But when I try to connect to the online server, the client fails("ERROR connecting: Operation timed out"). Any idea what happened?
Server(node.js):
var net = require('net');
var server = net.createServer(function (socket) {
socket.on("data", function(data){
socket.write(data.toString());
});
});
var port = process.env.VCAP_APP_PORT || 8081;
console.log(port);
server.listen(port);
Client(C, from http://www.linuxhowtos.org/C_C++/socket.htm):
#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");
while (1){
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 client must always connect on port 80 regardless of what process.env.VCAP_APP_PORT is set to. AppFog proxies requests from port 80 to the port your app is running on.
I am sorry if the title is misleading. I cannot really think of a better one. Here is some simple socket program that I have:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include <iostream>
#define BACKLOG 10
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
int portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
auto bindsuccess = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (bindsuccess < 0)
error("ERROR on binding");
struct pollfd newPollFD[1];
newPollFD[0].fd = sockfd;
newPollFD[0].events = POLLIN;
char buffer[256];
bzero(buffer,256);
listen(sockfd, BACKLOG);
struct sockaddr_in cli_addr;
socklen_t clilen = sizeof(cli_addr);
int newsockfd;
int rv = poll(newPollFD, 1, -1);
if (rv == -1) {
error("Error occured in Poll");
}
else {
if (newPollFD[0].revents & POLLIN){
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
int rwsuccess;
rwsuccess = read(newsockfd,buffer,255);
if (rwsuccess < 0)
error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
rwsuccess = write(newsockfd,"I got your message \n",18);
if (rwsuccess < 0)
error("ERROR writing to socket");
}
}
close(newsockfd);
close(sockfd);
return 0;
}
If I execute this code with a port number, and then telnet to that port number, the server listens in, but as soon as I send my first message, the connection terminates. I want the sever to keep on listening and sending acknowledgement back as many times as I send message from telnet. How do I accomplish that?
Thanks in advance!
The continue is curiously extraneous, and causes the compilation to break. (It is now corrected in your edit.) But, you are missing a for loop. And, you should add a check if the read returns 0.
for (;;) {
int rwsuccess;
rwsuccess = read(newsockfd,buffer,255);
if (rwsuccess < 0)
error("ERROR reading from socket");
if (rwsuccess == 0) break;
printf("Here is the message: %s\n",buffer);
rwsuccess = write(newsockfd,"I got your message \n",18);
if (rwsuccess < 0)
error("ERROR writing to socket");
}
C++ when used in networking is completely cryptic to me. Would anyone mind helping me break down the errors in this code? It was given to my class as an example of how not to make a UDP server.
I already notice a few issues like how the buffers are a fixed 256 bytes long, but for the most part I don't understand it. I'm more of a PHP/Java/JavaScript programmer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, 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 *) &cli_addr, sizeof(serv_addr));
portno = atoi(argv[2]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(cli_addr)) < 0)
error("ERROR on binding");
clilen = sizeof(cli_addr);
while(100)
{
bzero(buffer,256);
n = recvfrom(sockfd,buffer, 0, 255,
(struct sockaddr *) &serv_addr,&clilen);
printf("A client from %s port %d connected\n", inet_aton(cli_addr.sin_addr), htons(cli_addr.sin_port));
if (n < 0) error("Error reading from socket");
printf("Here is the message: %s\n",buffer);
n = sendto(sockfd,"I got your message",18,0,(struct sockaddr *) &serv_addr,sizeof(cli_addr));
if (n < 0) error("Error writing to socket");
}
close(sockfd);
return 0;
}
Have you tried it? Use nc/aka netcat to try sending UDP packets too it.
Oh and here is another clue from socket()'s man page
SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported
SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a fixed maximum length).
An you are right about the buffer size although it should not overflow - I would use 2^16 aka 65536 as this is the largest UDP packet supported in IPv4
socket function creates the socket handle for your server socket. bind function binds your socket handle to the specified IP address (INADDR_ANY) and port (via serv_addr). In your while loop, it receives data from a client via recvfrom function and prints the data out. sendto function sends the reply back to the client. close function closes your socket handle.
I have two versions of this code. In one version if the user inputs the phrase "GET /index.html" the server responds properly. In the second version, the "GET /index.html" phrase is built in without prompting the user. The second version hangs when reading a response from the server, any idea why?
First Version - Prompts user for phrase
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.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[10000];
portno = atoi("85");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error((char *)"ERROR opening socket");
server = gethostbyname("vilive.us");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error((char *)"ERROR connecting");
printf("Please enter the message: ");
memset(buffer,0,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error((char *)"ERROR writing to socket");
memset(buffer,0,256);
n = read(sockfd,buffer,500);
if (n < 0)
error((char *)"ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
Second Version - Automatically sends "GET /index.html" - This one hangs
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.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[10000];
//TEST
char getI[16];
getI[0]='G';
getI[1]='E';
getI[2]='T';
getI[3]=' ';
getI[4]='/';
getI[5]='i';
getI[6]='n';
getI[7]='d';
getI[8]='e';
getI[9]='x';
getI[10]='.';
getI[11]='h';
getI[12]='t';
getI[13]='m';
getI[14]='l';
getI[15]='\0';
portno = atoi("85");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error((char *)"ERROR opening socket");
server = gethostbyname("vilive.us");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error((char *)"ERROR connecting");
/*printf("Please enter the message: ");
memset(buffer,0,256);
fgets(buffer,255,stdin);*/
n = write(sockfd,getI,strlen(getI));
if (n < 0)
error((char *)"ERROR writing to socket");
memset(buffer,0,256);
n = read(sockfd,buffer,500);
if (n < 0)
error((char *)"ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
The request must be terminated with 2 carriage return and line feed pairs, this is missing in your second example.
char charI[] = "GET /index.html\r\n\r\n";
Please, switch to a modern version of HTTP. I find it amazing that your server agrees to reply, as the request isn't remotely valid HTTP.
This would be a suitable HTTP/1.1 request in your situation
char charI[] = "GET /index.html HTTP/1.1\r\nHost: vilive.us\r\nConnection: close\r\n\r\n";
note the Host header, that allow you to talk with sites that do virtual hosting, like ... stackoverflow.com and superuser.com that points to the same ip address. they only rely on the Host header to figure out if the user want to access stackoverflow.com or superuser.com.
Also, your should close the socket descriptor when you are done using the socket.