|
@@ -0,0 +1,116 @@
|
|
|
+/*
|
|
|
+ * File: server_tcp.c
|
|
|
+ * Author: Arthur Brandao
|
|
|
+ *
|
|
|
+ * Created on 14 novembre 2018
|
|
|
+ */
|
|
|
+
|
|
|
+#include "error.h"
|
|
|
+#include "server.h"
|
|
|
+
|
|
|
+/* --- Fonctions privées --- */
|
|
|
+void 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);
|
|
|
+ neterror(BIND_ERROR)
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Listen */
|
|
|
+ tmp = listen(this->socket, SOMAXCONN);
|
|
|
+ if (tmp == ERR) {
|
|
|
+ free(this);
|
|
|
+ neterror(BIND_ERROR)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void server_accept_tcp(Server this) {
|
|
|
+ /* Accept */
|
|
|
+ this->socket_client = accept(this->socket, NULL, NULL);
|
|
|
+ if (this->socket_client == ERR) {
|
|
|
+ free(this);
|
|
|
+ syserror("Erreur lors de la demande de connexion ", 3)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+ssize_t server_receive_tcp(Server this, char* buf, size_t size) {
|
|
|
+ int tmp;
|
|
|
+ /* Lecture message */
|
|
|
+ tmp = read(this->socket_client, buf, size);
|
|
|
+ if (tmp == ERR) {
|
|
|
+ free(this);
|
|
|
+ syserror("Erreur lors de la reception ", 3)
|
|
|
+ }
|
|
|
+ return tmp;
|
|
|
+}
|
|
|
+
|
|
|
+void server_send_tcp(Server this, char* msg) {
|
|
|
+ int tmp;
|
|
|
+ /* Envoi message */
|
|
|
+ tmp = write(this->socket_client, msg, strlen(msg) * sizeof (char));
|
|
|
+ if (tmp == ERR) {
|
|
|
+ free(this);
|
|
|
+ syserror("Erreur lors de l'envoi ", 3)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* --- 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);
|
|
|
+ neterror(SOCKET_ERROR)
|
|
|
+ }
|
|
|
+ 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);
|
|
|
+ neterror(SOCKET_ERROR)
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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;
|
|
|
+}
|
|
|
+
|
|
|
+void server_close_client(Server this) {
|
|
|
+ /* Declaration variable */
|
|
|
+ int tmp;
|
|
|
+
|
|
|
+ /* Que pour TCP */
|
|
|
+ if (this->type != SERV_TCP) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Ferme */
|
|
|
+ tmp = close(this->socket_client);
|
|
|
+ if (tmp == ERR) {
|
|
|
+ free(this);
|
|
|
+ syserror("Erreur lors de la fermeture de la socket ", 3)
|
|
|
+ }
|
|
|
+}
|