Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: C - server for http 8080 tcp  (Прочитано 654 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн victor00000

  • Автор темы
  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
C - server for http 8080 tcp
« : 18 Октября 2018, 21:39:45 »
// test_srv8080.c
// victor00000 (c) 2018
#define          _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include       <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

// Terminal: 1
// ~$ gcc test_srv8080.c -o test_srv8080 -lpthread
// ~$ ./test_srv8080
// Terminal: 2
// ~$ firefox http://127.0.0.1:8080/

typedef struct {
char *ip;
int i, cl;
} srv_ip;

char c_errtxt[] =
    "<html>"
    "<h1>"
    "404 Not Found" "</h1>" "</br>" "C - server for http (8080)" "</html>";

const char c_err404[] =
    "HTTP/1.1 404 Not Found\r\n"
    "Server: C - server for http (8080)\r\n"
    "Content-Length: %d\r\n"
    "Content-Type: text/html; charset=iso-8859-1\r\n" "\r\n";

char c_html[] =
    "<html>"
    "<h1>"
    "Hello World!" "</h1>" "</br></br>" "C - server for http (8080)" "</html>";

const char c_http[] =
    "HTTP/1.1 200 OK\r\n"
    "Server: C - server for http 8080\r\n"
    "Content-Length: %d\r\n" "Content-Type: text/html\r\n" "\r\n";

pthread_mutex_t mt;

//==================str add char
char *str_add(char *c, char b)
{
if (c == 0) {
c = malloc(2);
sprintf(c, "%c", b);
} else {
c = realloc(c, strlen(c) + 2);
sprintf(c + strlen(c), "%c", b);
}
return c;
}

//==================lock
void srv_lock()
{
pthread_mutex_lock(&mt);
}

//==================unlock
void srv_unlock()
{
pthread_mutex_unlock(&mt);
}

//===================error exit
void srv_error(const char *msg)
{
perror(msg);
exit(1);
}

//=============server port
int srv_port(int port)
{

int sockfd, portno;
struct sockaddr_in6 serv_addr;
int reuseaddr = 1;

sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0)
srv_error("ERROR opening socket");
if (setsockopt(sockfd, SOL_SOCKET,
       SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) < 0)
srv_error("ERROR setting REUSE socket option");
bzero((char *)&serv_addr, sizeof(serv_addr));

portno = port;
serv_addr.sin6_flowinfo = 0;
serv_addr.sin6_family = AF_INET;

serv_addr.sin6_addr = in6addr_any;
serv_addr.sin6_port = htons(portno);

if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
srv_error("ERROR on binding");

listen(sockfd, SOMAXCONN);
return sockfd;
}

//=====================accept
char *srv_accept(int s, int *cl)
{

struct sockaddr_in cli_addr;
socklen_t clilen = sizeof(cli_addr);

int newsockfd;

char *client_addr_ipv4 = (char *)
    malloc(256);

if (((newsockfd = accept(s, (struct sockaddr *)&cli_addr,
 &clilen))) < 0)
srv_error("ERROR on accept");
inet_ntop(AF_INET, &(cli_addr.sin_addr), client_addr_ipv4, 100);
*cl = newsockfd;
return client_addr_ipv4;
}

//===================pthread
void *srv_pth(void *a)
{
srv_ip *srv = (srv_ip *) a;
char *cstr = 0, b, bb = 0, *c;
int i = 0, e = 0;

while (1) {
if (read(srv->cl, &b, 1) != 1) {
e = 1;
break;
}

if (b != '\r')
cstr = str_add(cstr, b);

if ((b == '\r' || b == '\n') && i == 0) {
i = 1;
if (strncmp(cstr, "GET /index.", strlen("GET /index."))
    == 0
    || strncmp(cstr, "GET / ", strlen("GET / ")) == 0)
e = 200;
else
e = 404;
}

if ((b == '\r' || b == '\n') && bb == '\n')
break;
bb = b;
}
i = 0;
if (e == 200) {
asprintf(&c, c_http, strlen(c_html));
while (c[i]) {
if (write(srv->cl, &c[i], 1) != 1) {
e = 1;
break;
}
i++;
}
free(c);
}
if (e == 200) {
i = 0;
while (c_html[i]) {
if (write(srv->cl, &c_html[i], 1) != 1) {
e = 1;
break;
}
i++;
}
}

if (e == 404) {
i = 0;
asprintf(&c, c_err404, strlen(c_errtxt));
while (c[i]) {
if (write(srv->cl, &c[i], 1) != 1) {
e = 1;
break;
}
i++;
}
free(c);
}

if (e == 404) {
i = 0;
while (c_errtxt[i]) {
if (write(srv->cl, &c_errtxt[i], 1) != 1) {
e = 1;
break;
}
i++;
}
}
//=================a0
if (e == 200 || e == 404)
read(srv->cl, &b, 1);

srv_lock();
if (cstr != 0) {
printf("%s", cstr);
free(cstr);
cstr = 0;
}
printf("\nclose %s - %d\nERR: %d\n", srv->ip, srv->i, e);
srv_unlock();
close(srv->cl);
free(srv->ip);
free(srv);

return 0;
}

//===================m0
int main()
{
signal(SIGPIPE, SIG_IGN);
pthread_t t;
int ss, cl, i = 0;

ss = srv_port(8080);
char *ip = 0;

while (1) {
if (ip != 0) {
free(ip);
ip = 0;
}
ip = srv_accept(ss, &cl);
if (i > 1024)
i = 0;
i++;
srv_lock();
printf("\nopen %s - %d\n", ip, i);
srv_unlock();
int *scl;
srv_ip *srv = malloc(sizeof(srv_ip));

asprintf(&srv->ip, "%s", ip);
srv->cl = cl;
srv->i = i;
scl = malloc(sizeof(int));
*scl = cl;
while (pthread_create(&t, 0, srv_pth, srv)) {
}
pthread_detach(t);
}
return 0;
}
http://paste.ubuntu.com/p/DYbD7CTmrt/
Wars ~.o

 

Страница сгенерирована за 0.049 секунд. Запросов: 25.