ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hey I am using a simple html server kind of and I have run into an issue where accept is triggered but recv doesn't recv data so recv halts the program? Is there any way to fix this problem without using select? The file is big but I can try to paste it here. Should be able to compile this source with gcc main.c.
main.c
The connected partner is not bound to send anything. If you don't wish to use asynchron-io with poll/select, you can use `inetd` to deal with networking.
I just put those functions after the accept function and before the recv functions. If i did something wrong let me know but for now im gonna call this one solved. --not solved i shouldn't have assumed it was--
The connected partner is not bound to send anything. If you don't wish to use asynchron-io with poll/select, you can use `inetd` to deal with networking.
omg I think it was just a simple error forget to change the socket i was disconnecting. it seems to be working now. If it doesn't give me any problems i will mark this as solved and post the working cool html server skeleton.
Ok thank you for an alternative @NevemTeve it was a good answer to my original question. Here is a working base for anyone that wants to build an html game. It should compile with gcc main.c if you saved the code into a file called main.c. Of course it needs a lot of work to be a game it could be a good start though.
Code:
#include <arpa/inet.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>
#define KB 1024
#define MB 1048576
#define GIG 1073741824
#define BUF_SIZE KB
#define MAX_CLIENTS 300
char http_not_found[] = "HTTP/1.0 404 Not Found\n\0";
char http_ok[] = "HTTP/1.0 200 OK\n\0";
char *getFileType(char *file);
long long int skipspaces(char **ptr);
long long int getstring(char **string, char *buffer, long long int size);
int send_data(int socket, char *format, ...);
void send_file(int socket, char *filepath);
void debug_string(char *string);
int main()
{
fd_set readfds;
int max_sd;
int html_socket;
int client_socket[MAX_CLIENTS];
int sd;
struct sockaddr_in addr;
struct sockaddr_in peer;
struct hostent *host;
struct in6_addr inAddr;
char peerip[128];
int peerlen;
int running;
time_t timenow;
struct tm *timeinfo;
time (&timenow);
timeinfo = localtime(&timenow);
char *header, *request, *path;
char *temp, *iter;
int connfd;
char get[5], http[10];
char buffer[BUF_SIZE];
char *contentType;
long long int i = 0;
struct timeval tv;
setbuf(stdout, NULL);
tv.tv_sec=0;
tv.tv_usec=1;
header = (char*)malloc(BUF_SIZE);
request = (char*)malloc(BUF_SIZE);
path = (char*)malloc(100);
memset(&peerip, 0, 128);
memset(header, 0, BUF_SIZE);
memset(request, 0, BUF_SIZE);
memset(path, 0, 100);
memset(&get, 0, 5);
memset(&http, 0, 10);
memset(&buffer, 0, BUF_SIZE);
memset(&addr, 0, sizeof(addr));
memset(&peer, 0, sizeof(peer));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(80);
html_socket = socket(AF_INET, SOCK_STREAM, 0);
if(html_socket < 0){
perror("Error creating socket!");
exit(1);
}
printf("Socket created...\n");
if (bind(html_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error binding socket to port!");
exit(1);
}
printf("Binding done...\n");
listen(html_socket, 0);
printf("Listening to socket...\n");
peerlen = sizeof(peer);
running = 1;
for(i=0;i<MAX_CLIENTS;i++)
{
client_socket[i] = 0;
}
while(running) {
FD_ZERO(&readfds);
FD_SET(html_socket, &readfds);
max_sd = html_socket;
for ( i = 0 ; i < MAX_CLIENTS ; i++)
{
//socket descriptor
sd = client_socket[i];
//if valid socket descriptor then add to read list
if(sd > 0)
FD_SET( sd , &readfds);
//highest file descriptor number, need it for the select function
if(sd > max_sd)
max_sd = sd;
}
select(max_sd + 1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(html_socket, &readfds))
{
if ( (connfd = accept(html_socket, (struct sockaddr *)&peer, &peerlen)) < 0) {
printf("Got Here!\n");
perror("Error accepting connection!");
exit(1);
}
inet_ntop(AF_INET, &(peer.sin_addr), peerip, 128);
inet_pton(AF_INET, peerip, &inAddr);
host = gethostbyaddr(&inAddr, sizeof(inAddr), AF_INET);
printf("---Connection received from: %s [IP= %s]---\n", host->h_name, peerip);
for(i=0;i<MAX_CLIENTS;i++)
if(client_socket[i]==0){
client_socket[i] = connfd;
break;
}
}
for (i=0;i<MAX_CLIENTS; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//gets the request from the connection
recv(sd, request, 100, MSG_PEEK);
if (recv(sd, buffer, BUF_SIZE, 0)<=0){
close(sd);
client_socket[i] = 0;
continue;
}
request[100] = 0;
printf("--Recieved data in (buffer):\n%s\nEnd buffer--\n", buffer);
printf("Processing request...\n");
//parse request
memset(&get, 0, 5);
iter = request;
getstring(&iter, get, 5);
skipspaces(&iter);
path[0] = 0;
path[1] = 0;
getstring(&iter, path, 100);
skipspaces(&iter);
getstring(&iter, http, 10);
printf("get: %3s, path: %s, http: %s\n", get, path, http);
contentType = getFileType(path+1);
sprintf(header, "Date: %sHostname: Space:80\nLocation: %s\nContent-Type: %s\n\n\0", asctime(timeinfo), path, contentType);
if(strncmp("/index.html\0", path, 12) == 0){
send(sd, http_ok, strlen(http_ok), 0); //Send OK
send(sd, header, strlen(header), 0);
send_data(sd,
"<html lang=\"en\">\n"
"<title>Space</title>\n"
"<head>\n"
"</head>\n"
"<body>\n"
"A pagan says, \"Finally, Hello world!\"<br>\n"
"<image src=\"favicon.ico\" alt=\"favicon.ico\" height=\"25\" width=\"25\">\n"
"<form method=\"post\" action=\"index.html\">\n"
" <label for=\"email\">Username:</label><input type=\"text\" id=\"email\" name=\"email\" value=\"\"><br>\n"
" <label for=\"pass\">Password:</label><input type=\"password\" id=\"pass\" name=\"pass\" value=\"\"><br>\n"
"<input type=\"submit\" value=\"Login\\Create\">\n"
"</form>\n"
"</body>\n"
"</html>\0");
} else if (strncmp("/favicon.ico\0", path, 13) == 0){
send(sd, http_ok, strlen(http_ok), 0); // Send OK
send(sd, header, strlen(header), 0);
send_file(sd, path+1);
}
else {
send(sd, http_not_found, strlen(http_not_found), 0);
send_data(sd,
"<html lang=\"en\">\n"
"<title></title>\n"
"<head>\n"
"</head>\n"
"<body style=\"text-align:center;\">\n"
"<br><br><br><br>%s"
"</body>\n"
"</html>\n", http_not_found);
}
buffer[0] = 0;
get[0] = 0;
path[0] = 0;
http[0] = 0;
printf("Processing completed...\n");
close(sd);
client_socket[i]=0;
}
}
}
close(html_socket);
free(header);
free(request);
free(path);
}
char *getFileType(char *file){
char *temp;
if ((temp = strstr(file, ".html")) != NULL) {
return "text/html";
} else if ((temp = strstr(file, ".pdf")) != NULL) {
return "application/pdf";
} else if ((temp = strstr(file, ".txt")) != NULL) {
return "text/html";
} else {
return "Uknown";
}
}
long long int skipspaces(char **ptr){
long long int c = 0;
while(**ptr == ' '&& **ptr != 0){
(*ptr)++;
c++;
}
return c;
}
long long int getstring(char **string, char *buffer, long long int size){
long long int c = 0;
while(**string != ' ' && **string != '\n' && **string !='\r' && (c<(size-1))){
*buffer = **string;
buffer++;
(*string)++;
c++;
}
*buffer = 0;
return c;
}
int send_data(int socket, char *format, ...){
va_list args;
char buffer[KB];
int ret;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
ret = send(socket, buffer, strlen(buffer), 0);
return ret;
}
void send_file(int socket, char *filepath){
FILE *fileptr;
char buffer[KB];
if ((fileptr = fopen(filepath, "r")) == NULL ) {
send(socket, http_not_found, strlen(http_not_found), 0); //sends HTTP 404
} else {
memset(&buffer, 0, sizeof(buffer));
while (!feof(fileptr)) { //sends the file
fread(&buffer, sizeof(buffer)-1, 1, fileptr);
send(socket, buffer, sizeof(buffer), 0);
memset(&buffer, 0, sizeof(buffer));
}
}
fclose(fileptr);
}
void debug_string(char *string){
int i = 0;
puts("**debug**");
while(string[i]!=0)
{
printf("%X ", string[i++]);
}
printf("%X\n", string[i]);
i=0;
while(string[i]!=0)
{
printf("%2c ", string[i++]);
}
printf("%c\n", string[i]);
puts("**debug**");
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.