diff options
| author | iceyrazor <iceyrazor@mailfence.com> | 2026-09-25 21:12:03 -0500 |
|---|---|---|
| committer | iceyrazor <iceyrazor@mailfence.com> | 2026-09-25 21:12:03 -0500 |
| commit | 7e287a8ca7164e871965339196511fdcf0248921 (patch) | |
| tree | d69ba74fd8ec0981c681d89aadbcda8aeb75e5d5 | |
init
| -rw-r--r-- | README.md | 3 | ||||
| -rwxr-xr-x | Server.c | 44 | ||||
| -rwxr-xr-x | Server.h | 43 | ||||
| -rwxr-xr-x | launch-socket-old.c | 192 | ||||
| -rwxr-xr-x | launch-socket.c | 189 | ||||
| -rwxr-xr-x | launch-web.c | 101 |
6 files changed, 572 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..68655d2 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# socket + +my small websocket and webserver libs. diff --git a/Server.c b/Server.c new file mode 100755 index 0000000..3fb55c6 --- /dev/null +++ b/Server.c @@ -0,0 +1,44 @@ +#include <sys/socket.h> +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <Server.h> + +struct Server server_constructor(int domain, int service, int protocol, ulong interface, int port, int backlog, pthread_t(*launch)(struct Server *server)){ + struct Server server; + + server.domain=domain; + server.service=service; + server.protocol=protocol; + server.interface=interface; + server.port=port; + server.backlog=backlog; + + server.address.sin_family=domain; + server.address.sin_port=htons(port); + server.address.sin_addr.s_addr=htonl(interface); + + server.socket = socket(domain,service,protocol); + + if(server.socket == 0){ + perror("failed to connect to socket...\n"); + exit(1); + } + + if (bind(server.socket, (struct sockaddr *)&server.address, sizeof(server.address)) < 0){ + perror("failed to bind socket...\n"); + exit(1); + } + + if(listen(server.socket, server.backlog) < 0){ + perror("failed to start listening...\n"); + exit(1); + } + + server.accepted_socket=NULL; + + server.launch=launch; + server.running=true; + + return server; +}; diff --git a/Server.h b/Server.h new file mode 100755 index 0000000..2192e2b --- /dev/null +++ b/Server.h @@ -0,0 +1,43 @@ +#ifndef Server_h +#define Server_h + +#include <sys/socket.h> +#include <netinet/in.h> +#include <stdbool.h> +#include <pthread.h> + +struct AcceptedSocket{ + int socketFD; + struct sockaddr_in address; + int error; + bool succ; + pthread_t thread_id; + bool shutdown; + + struct AcceptedSocket *next; +}; + +struct Server{ + int domain; + int service; + int protocol; + u_long interface; + int port; + int backlog; + bool running; + + struct sockaddr_in address; + + int socket; + char *html_folder; + + struct AcceptedSocket *accepted_socket; + + pthread_t (*launch)(struct Server *server); + void (*on_message)(struct Server *server, char message[], ssize_t amountRecv, int socketFD); + void (*on_disconnect)(struct Server *server, int socketFD); +}; + +struct Server server_constructor(int domain, int service, int protocol, u_long interface, int port, int backlog, pthread_t (*launch)(struct Server *server)); + +#endif /* Server_h */ diff --git a/launch-socket-old.c b/launch-socket-old.c new file mode 100755 index 0000000..19fa1d7 --- /dev/null +++ b/launch-socket-old.c @@ -0,0 +1,192 @@ +#include <unistd.h> +#include <bits/pthreadtypes.h> +#include <pthread.h> +#include <netinet/in.h> +#include <stdio.h> +#include "Server.c" +#include "Server.h" +#include <sys/socket.h> +#include <poll.h> +#include <stdbool.h> + +struct AcceptedSocket* acceptIncoming(struct Server *server){ + int serverSocketFd=server->socket; + + struct sockaddr_in clientAddress; + int ClientAddressSize = sizeof(struct sockaddr); + int clientSocketFD = accept(serverSocketFd,(struct sockaddr *)&clientAddress,&ClientAddressSize); + + if(server->running){ + struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket)); + acceptedSocket->address=clientAddress; + acceptedSocket->socketFD=clientSocketFD; + acceptedSocket->succ=clientSocketFD>0; + acceptedSocket->next=NULL; + acceptedSocket->shutdown=false; + + if(!acceptedSocket){ + acceptedSocket->error=clientSocketFD; + } else { + if(server->running){ + struct AcceptedSocket *sel_socket=server->accepted_socket; + + if(sel_socket==NULL){ + server->accepted_socket=acceptedSocket; + } else { + while(1){ + if(sel_socket->next==NULL){ + sel_socket->next=acceptedSocket; + break; + } else { + sel_socket=sel_socket->next; + } + } + } + } + } + return acceptedSocket; + } else { + return NULL; + } +} + +struct recv_data_arg{ + int socketFD; + struct Server *server; + struct AcceptedSocket *curr_socket; +}; + + +void *recv_data(void *threadarg){ + struct recv_data_arg *recv_d_arg; + recv_d_arg=(struct recv_data_arg *) threadarg; + + while(recv_d_arg->server->running){ + char buffer[30000]={0}; + ssize_t amountRecv=recv(recv_d_arg->socketFD, buffer, 30000, 0); + + if(recv_d_arg->server->running){ + if(amountRecv==0) break; + + recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD); + } + } + + + + recv_d_arg->curr_socket->shutdown=true; + close(recv_d_arg->socketFD); + if(recv_d_arg->server->on_disconnect){ + recv_d_arg->server->on_disconnect(recv_d_arg->server,recv_d_arg->socketFD); + } + free(recv_d_arg); + + + pthread_exit(NULL); +} + +void cleanup_conns(struct Server *server){ + if(server->accepted_socket){ + struct AcceptedSocket *sel_socket=server->accepted_socket; + struct AcceptedSocket *prev_socket=server->accepted_socket; + struct AcceptedSocket *prev2_socket=server->accepted_socket; + + while (sel_socket!=NULL){ + sel_socket=sel_socket->next; + if(prev_socket->shutdown==true){ + if(prev_socket==server->accepted_socket){ + free(server->accepted_socket); + server->accepted_socket=sel_socket; + } else { + free(prev2_socket->next); + prev2_socket->next=sel_socket; + } + } else { + prev2_socket=prev_socket; + } + prev_socket=sel_socket; + } + } +} + +void *await_client(void *threadarg){ + struct Server *server; + server=(struct Server *) threadarg; + while (server->running){ + printf("\n=== WAITING FOR CONNECTION ===\n\n"); + + struct AcceptedSocket* new_socket = acceptIncoming(server); + if(server->running){ + if(new_socket->succ==0){ free(new_socket); } else { + + struct recv_data_arg *recv_d_arg; + recv_d_arg=malloc(sizeof(* recv_d_arg)); + recv_d_arg->socketFD=new_socket->socketFD; + recv_d_arg->server=server; + recv_d_arg->curr_socket=new_socket; + + int thread_err=pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg); + } + + cleanup_conns(server); + } + } + + pthread_exit(NULL); +} + +void server_close_socket(struct Server *server){ + server->running=false; + + struct AcceptedSocket *sel_socket_A=server->accepted_socket; + while(sel_socket_A!=NULL){ + close(sel_socket_A->socketFD); + sel_socket_A->shutdown=true; + sel_socket_A=sel_socket_A->next; + } + + int shuterr=shutdown(server->socket,SHUT_RDWR); + int closeerr=close(server->socket); + + sleep(2); + + //this took way to long to make + /* + if(server->accepted_socket!=NULL){ + while(server->accepted_socket!=NULL){ + struct AcceptedSocket *sel_socket=server->accepted_socket; + struct AcceptedSocket *prev_socket=server->accepted_socket; + struct AcceptedSocket *prev2_socket=server->accepted_socket; + while(sel_socket!=NULL){ + prev2_socket=prev_socket; + prev_socket=sel_socket; + sel_socket=sel_socket->next; + } + + if(prev2_socket->next==NULL){ + free(server->accepted_socket); + server->accepted_socket=NULL; + } else { + free(prev2_socket->next); + prev2_socket->next=NULL; + } + } + } + */ + cleanup_conns(server); + + + + printf("\nshutdown with %d : %d\n",shuterr,closeerr); + free(server); +} + +pthread_t launch_socket(struct Server *server){ + int addrlen= sizeof(server->address); + + printf("running on port: %d\n",server->port); + + pthread_t id; + int thread_err=pthread_create(&id, NULL, await_client, (void *) server); + return id; +} diff --git a/launch-socket.c b/launch-socket.c new file mode 100755 index 0000000..e607f62 --- /dev/null +++ b/launch-socket.c @@ -0,0 +1,189 @@ +#include <unistd.h> +#include <bits/pthreadtypes.h> +#include <pthread.h> +#include <netinet/in.h> +#include <stdio.h> +#include "Server.c" +#include "Server.h" +#include <sys/socket.h> +#include <poll.h> +#include <stdbool.h> +#include <string.h> + +struct AcceptedSocket* acceptIncoming(struct Server *server){ + int serverSocketFd=server->socket; + + struct sockaddr_in clientAddress; + socklen_t ClientAddressSize = sizeof(struct sockaddr); + int clientSocketFD = accept(serverSocketFd,(struct sockaddr *)&clientAddress,&ClientAddressSize); + + if(server->running){ + struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket)); + acceptedSocket->address=clientAddress; + acceptedSocket->socketFD=clientSocketFD; + acceptedSocket->succ=clientSocketFD>0; + acceptedSocket->next=NULL; + acceptedSocket->shutdown=false; + + if(!acceptedSocket){ + acceptedSocket->error=clientSocketFD; + } else { + if(server->running){ + struct AcceptedSocket *sel_socket=server->accepted_socket; + + if(sel_socket==NULL){ + server->accepted_socket=acceptedSocket; + } else { + while(1){ + if(sel_socket->next==NULL){ + sel_socket->next=acceptedSocket; + break; + } else { + sel_socket=sel_socket->next; + } + } + } + } + } + return acceptedSocket; + } else { + return NULL; + } +} + +struct recv_data_arg{ + int socketFD; + struct Server *server; + struct AcceptedSocket *curr_socket; +}; + + +void *recv_data(void *threadarg){ + struct recv_data_arg *recv_d_arg; + recv_d_arg=(struct recv_data_arg *) threadarg; + + while(recv_d_arg->server->running){ + char buffer[30000]={0}; + ssize_t amountRecv=recv(recv_d_arg->socketFD, buffer, 30000, 0); + + if(recv_d_arg->server->running){ + if(amountRecv==0) break; + + recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD); + } + } + + + + recv_d_arg->curr_socket->shutdown=true; + close(recv_d_arg->socketFD); + if(recv_d_arg->server->on_disconnect){ + recv_d_arg->server->on_disconnect(recv_d_arg->server,recv_d_arg->socketFD); + } + free(recv_d_arg); + + + pthread_exit(NULL); +} + +void cleanup_conns(struct Server *server){ + if(server->accepted_socket){ + struct AcceptedSocket *sel_socket=server->accepted_socket; + struct AcceptedSocket *prev_socket=server->accepted_socket; + struct AcceptedSocket *prev2_socket=server->accepted_socket; + + while (sel_socket!=NULL){ + sel_socket=sel_socket->next; + if(prev_socket->shutdown==true){ + if(prev_socket==server->accepted_socket){ + free(server->accepted_socket); + server->accepted_socket=sel_socket; + } else { + free(prev2_socket->next); + prev2_socket->next=sel_socket; + } + } else { + prev2_socket=prev_socket; + } + prev_socket=sel_socket; + } + } +} + +void *await_client(void *threadarg){ + struct Server *server; + server=(struct Server *) threadarg; + while (server->running){ + printf("\n=== WAITING FOR CONNECTION ===\n\n"); + + struct AcceptedSocket* new_socket = acceptIncoming(server); + if(server->running){ + if(new_socket->succ==0){ free(new_socket); } else { + + struct recv_data_arg *recv_d_arg; + recv_d_arg=malloc(sizeof(* recv_d_arg)); + recv_d_arg->socketFD=new_socket->socketFD; + recv_d_arg->server=server; + recv_d_arg->curr_socket=new_socket; + + int thread_err=pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg); + } + } + } + + pthread_exit(NULL); +} + +void *cleanup_loop(void *threadarg){ + struct Server *server; + server=(struct Server *) threadarg; + while(server->running){ + cleanup_conns(server); + sleep(60); + } + + pthread_exit(NULL); +} + +void server_close_socket(struct Server *server){ + server->running=false; + + struct AcceptedSocket *sel_socket_A=server->accepted_socket; + while(sel_socket_A!=NULL){ + close(sel_socket_A->socketFD); + sel_socket_A->shutdown=true; + sel_socket_A=sel_socket_A->next; + } + + int shuterr=shutdown(server->socket,SHUT_RDWR); + int closeerr=close(server->socket); + + sleep(2); + cleanup_conns(server); + + printf("\nshutdown with %d : %d\n",shuterr,closeerr); +} + +pthread_t launch_socket(struct Server *server){ + int addrlen= sizeof(server->address); + + printf("running on port: %d\n",server->port); + + pthread_t id2; + int thread_err2=pthread_create(&id2, NULL, cleanup_loop, (void *) server); + if (thread_err2!=0){ + fprintf(stderr,"ERROR WITH CLEANUP LOOP: %d\n",thread_err2); + perror("cleanup loop err"); + exit(-1); + } + + pthread_t id; + int thread_err=pthread_create(&id, NULL, await_client, (void *) server); + if (thread_err!=0){ + fprintf(stderr,"ERROR WITH AWAIT CLIENT: %d\n",thread_err); + perror("await client error"); + exit(-1); + } + + return id; +}
\ No newline at end of file diff --git a/launch-web.c b/launch-web.c new file mode 100755 index 0000000..e53eb56 --- /dev/null +++ b/launch-web.c @@ -0,0 +1,101 @@ +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <pthread.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <Server.c> +#include <iceys-utils.h> + +void server_close(struct Server *server){ + server->running=false; + + sleep(1); + + int shuterr=shutdown(server->socket,SHUT_RDWR); + int closeerr=close(server->socket); + + printf("\nshutdown with %d : %d\n",shuterr,closeerr); + //free(server); +} + +void *server_loop(void *threadarg){ + struct Server *server; + server=(struct Server *) threadarg; + + char buffer[30000]={0}; + int addrlen= sizeof(server->address); + + int new_socket; + char *meta_type="\r\ncontent-type: text/html\r\n\r\n"; + + printf("running on port: %d",server->port); + + while (server->running){ + char metadata[100]=""; + + printf("\n=== WAITING FOR CONNECTION ===\n\n"); + new_socket = accept(server->socket, (struct sockaddr *)&server->address, (socklen_t *)&addrlen); + + if(new_socket<0){ break; } + + if(read(new_socket,buffer,29999)<0){ printf("\nREAD FAILED\n\n"); close(new_socket); break; } + buffer[29999]='\0'; + + printf("%s\n",buffer); + + char response[30000] = {0}; + + + char file_req_buf[1000]={0}; + strcpy(file_req_buf,server->html_folder); + char file_req[1000]={0}; + str_before_nth(buffer+5, file_req, ' ', 0); + strcat(file_req_buf,file_req); + + + printf("file req: %s====\n",file_req_buf); + + + if(strncmp(file_req, "", 1) == 0){ + strcat(file_req_buf,"index.html"); + } + + char file_req_buf2[1000]={0}; + strcpy(file_req_buf2,str_remove_all(file_req_buf,"..")); + printf("file ret: %s====\n",file_req_buf); + + + if (access(file_req_buf, F_OK) == 0) { + char *status="HTTP/1.0 200 OK"; + memcpy(metadata,status,strlen(status)); + memcpy(metadata+strlen(metadata),meta_type,strlen(meta_type)); + memcpy(response, metadata, strlen(metadata)); + FILE* file=fopen(file_req_buf, "r"); + fread(response + strlen(metadata), 30000 - strlen(metadata) - 1, 1, file); + fclose(file); + } else { + char *status="HTTP/1.0 404 Not Found"; + memcpy(metadata,status,strlen(status)); + memcpy(metadata+strlen(metadata),meta_type,strlen(meta_type)); + memcpy(response, metadata, strlen(metadata)); + char* error = "error 404 file not found"; + memcpy(response + strlen(metadata), error, strlen(error)); + } + + printf("\n\n==response==\n%s\n",response); + + write(new_socket, response, strlen(response)); + close(new_socket); + } + + pthread_exit(NULL); +} + +pthread_t launch(struct Server *server){ + //HTTP/1.0 200 OK + + pthread_t id; + int thread_err=pthread_create(&id, NULL, server_loop, (void *) server); + return id; +} |
