123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- /*
- * File: server_tcp.c
- * Author: Arthur Brandao
- *
- * Created on 14 novembre 2018
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
- #include "error.h"
- #include "server.h"
- /* --- Extern --- */
- extern int serrno;
- extern int errno;
- /* --- Fonctions privées --- */
- boolean server_bind_tcp(Server this, int port) {
- /* Declaration variable */
- int tmp;
- /* Bind */
- this->serv.sin_family = AF_INET;
- this->serv.sin_port = htons(port);
- this->serv.sin_addr.s_addr = htonl(INADDR_ANY);
- tmp = bind(this->socket, (struct sockaddr*) &this->serv, sizeof (struct sockaddr_in));
- if (tmp == ERR) {
- free(this);
- serrno = SEBIND;
- addperror("Impossible de bind la socket");
- return false;
- }
- /* Listen */
- tmp = listen(this->socket, SOMAXCONN);
- if (tmp == ERR) {
- free(this);
- serrno = SEBIND;
- addperror("Impossible d'ecouter");
- return false;
- }
-
- return true;
- }
- boolean server_accept_tcp(Server this) {
- /* Accept */
- this->socket_client = accept(this->socket, NULL, NULL);
- if (this->socket_client == ERR) {
- serrno = SEACCEPT;
- addperror("Impossible d'accepter");
- return false;
- }
-
- return true;
- }
- ssize_t server_receive_tcp(Server this, char* buf, size_t size) {
- int tmp;
- /* Lecture message */
- memset(buf, 0, size);
- tmp = read(this->socket_client, buf, size);
- if (tmp == ERR) {
- serrno = SERECEIVE;
- addperror("Impossible de récupèrer les données");
- return ERR;
- }
- //Si on continue sans avoir modifier buffer (et donc un read non bloquant) signe d'une deconnexion
- if(buf[0] == '\0'){
- serrno = SEABORT;
- adderror("Aucune données émise par le client");
- return ERR;
- }
- return tmp;
- }
- boolean server_send_tcp(Server this, char* msg) {
- int tmp;
- /* Envoi message */
- tmp = write(this->socket_client, msg, strlen(msg) * sizeof (char));
- if (tmp == ERR) {
- //Si connexion coupé (et SIGPIPE)
- if(errno == EPIPE){
- serrno = SEABORT;
- } else {
- serrno = SESEND;
- }
- addperror("Impossible d'envoyer les données");
- return false;
- }
-
- return true;
- }
- /* --- Fonctions publiques --- */
- Server server_create_tcp() {
- /* Declaration variable */
- Server this;
- int tmp, option;
- /* Creation socket */
- this = malloc(sizeof (struct server));
- this->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (this->socket == ERR) {
- free(this);
- serrno = SESOCKET;
- addperror("Impossible de créer la socket");
- return NULL;
- }
- this->addr = sizeof (struct sockaddr_in);
- memset(&this->serv, 0, sizeof (struct sockaddr_in));
- /* Indique la possibilité de réutiliser la socket même si elle est en TIME_WAIT */
- option = 1;
- tmp = setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof (option));
- if (tmp == -1) {
- free(this);
- serrno = SESOCKET;
- addperror("Impossible de modifier les options de la socket");
- return NULL;
- }
- /* Lien fonctions */
- this->server_bind = server_bind_tcp;
- this->server_receive = server_receive_tcp;
- this->server_send = server_send_tcp;
- this->server_accept = server_accept_tcp;
- /* Type de serveur */
- this->type = SERV_TCP;
- /* Retour */
- return this;
- }
- boolean server_close_client(Server this) {
- /* Que pour TCP */
- if (this->type != SERV_TCP) {
- serrno = SETYPE;
- adderror("Type de la socket incorrect");
- return false;
- }
-
- /* Ferme */
- if (close(this->socket_client) == ERR) {
- serrno = SECLOSE;
- addperror("Impossible de fermer la socket");
- return false;
- }
-
- return true;
- }
|