Selaa lähdekoodia

improved client, char buffers replaced by streams, test packages

Kajetan Johannes Hammerle 5 vuotta sitten
vanhempi
commit
2f5bcad8ba
10 muutettua tiedostoa jossa 386 lisäystä ja 177 poistoa
  1. 197 0
      Client.c
  2. 20 0
      Client.h
  3. 39 0
      ClientMain.c
  4. 2 2
      Makefile
  5. 29 18
      Server.c
  6. 1 0
      Server.h
  7. 26 12
      ServerMain.c
  8. 62 19
      Stream.c
  9. 10 6
      Stream.h
  10. 0 120
      client.c

+ 197 - 0
Client.c

@@ -0,0 +1,197 @@
+#include <sys/socket.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#define __USE_MISC
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include "Stream.h"
+#include "Client.h"
+
+void clientInitDefaults(Client* c)
+{
+    c->port = -1;
+    c->socket = -1;
+}
+
+int clientInit(Client* c, char* ip, short port)
+{
+    c->port = port;
+    
+    c->socket = socket(AF_INET, SOCK_STREAM, 0);
+    if(c->socket == -1)
+    {
+        perror("Cannot create socket");
+        clientRemove(c);
+        return -1;
+    }
+
+    struct sockaddr_in socketData;
+    memset(&socketData, 0, sizeof(struct sockaddr_in));
+    socketData.sin_family = AF_INET;
+    socketData.sin_port = htons(port);
+    if(inet_aton(ip, &socketData.sin_addr) == 0)
+    {
+        printf("'%s' is not a valid ip\n", ip);
+        clientRemove(c);
+        return -1;
+    }
+
+    if(connect(c->socket, (struct sockaddr*) &socketData, sizeof(struct sockaddr_in)) == 0)
+    {
+        printf("Connection with server (%s) established\n", inet_ntoa(socketData.sin_addr));
+        Stream in;
+        streamInit(&in);
+        if(clientReceive(c, &in) == -1)
+        {
+            printf("Server did not respond");
+            clientRemove(c);
+            return -1;
+        }
+        else
+        {
+            char answer;
+            if(streamGetChar(&in, &answer) == -1)
+            {
+                printf("Server sent an invalid response");
+                clientRemove(c);
+                return -1;
+            }
+            else if(answer > 0)
+            {
+                printf("Successfully received server response\n");
+                char welcome[100];
+                streamGetChars(&in, welcome, 100);
+                printf("%s\n", welcome);
+            }
+            else
+            {
+                char error[100];
+                streamGetChars(&in, error, 100);
+                printf("%s\n", error);
+                clientRemove(c);
+                return -1;
+            }
+        }
+    }
+    else
+    {
+        perror("No server is available");
+        clientRemove(c);
+        return -1;
+    }
+
+    return 0;
+}
+
+int clientReceive(Client* c, Stream* in)
+{
+    int size = recv(c->socket, in->data, in->size, 0);
+    if(size > 0)
+    {
+        in->size = size;
+        return 0;
+    }
+    return -1;
+}
+
+void clientRemove(Client* c)
+{
+    c->port = -1;
+    
+    if(c->socket != -1)
+    {
+        if(close(c->socket) != 0)
+        {
+            perror("Cannot close client socket");
+        }
+        else
+        {
+            printf("socket closed\n");
+        }
+    }
+}
+
+void clearInput()
+{
+    int c = getchar();  
+    while(c != EOF && c != '\n')
+    {
+        c = getchar(); 
+    }
+}
+
+int readInt()
+{
+    int type;
+    while(scanf("%d", &type) == 0)
+    {
+        printf("Not a number\n");
+        clearInput();
+    }
+    clearInput();
+    return type;
+}
+
+void clientWaitForData(Client* c)
+{
+    while(1)
+    {
+        printf("Choose a package: ");
+        int type = readInt();
+        
+        if(type == -1)
+        {
+            break;
+        }
+        else if(type >= 0 && type < 4)
+        {
+            Stream out;
+            streamInit(&out);
+            streamWriteChar(&out, type);
+            
+            switch(type)
+            {
+                case 0:
+                    printf("first number: ");
+                    streamWriteInt(&out, readInt());
+                    printf("second number: ");
+                    streamWriteInt(&out, readInt());
+                    break;
+                case 1:
+                    printf("text: ");
+                    char buffer[128];
+                    fgets(buffer, 128, stdin);
+                    if(strlen(buffer) == 127 && buffer[126] != '\n')
+                    {
+                        clearInput();
+                    }
+                    streamWriteChars(&out, buffer);
+                    break;
+                case 2:
+                    // empty
+                    break;
+            }
+            
+            if(clientSendData(c, &out) == -1)
+            {
+                break;
+            }
+        }
+        else
+        {
+            printf("%d is not a valid package number\n", type);
+        }
+    }
+}
+
+int clientSendData(Client* c, Stream* s)
+{
+    if(send(c->socket, s->data, s->index, MSG_NOSIGNAL) == -1)
+    {
+        perror("Cannot send data");
+        return -1;
+    }
+    return 0;
+}

+ 20 - 0
Client.h

@@ -0,0 +1,20 @@
+#ifndef CLIENT_H
+#define CLIENT_H
+
+typedef struct Client
+{
+    short port;
+    int socket;
+} Client;
+
+void clientInitDefaults(Client* c);
+int clientInit(Client* c, char* ip, short port);
+void clientRemove(Client* c);
+
+int clientReceive(Client* c, Stream* in); 
+void clientWaitForData(Client* c);
+
+int clientSendData(Client* c, Stream* s);
+
+#endif
+

+ 39 - 0
ClientMain.c

@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "Stream.h"
+#include "Client.h"
+
+Client client;
+
+void interruptHandler(int signal)
+{
+    clientRemove(&client);
+    exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+    if(argc < 2)
+    {
+        printf("Usage: %s server_address\n", argv[0]);
+        return EXIT_FAILURE;
+    }
+    
+    clientInitDefaults(&client);
+    
+    signal(SIGINT, interruptHandler);
+    signal(SIGKILL, interruptHandler);
+    
+    if(clientInit(&client, argv[1], 6543) == -1)
+    {
+        return EXIT_FAILURE;
+    }
+
+    clientWaitForData(&client);
+
+    clientRemove(&client);
+    return EXIT_SUCCESS;
+}

+ 2 - 2
Makefile

@@ -14,8 +14,8 @@ run_server: server
 	./server
 
 
-client: client.c Stream.c Stream.h
-	gcc $(FLAGS) -o $@ client.c Stream.c
+client: ClientMain.c Client.c Client.h Stream.c Stream.h
+	gcc $(FLAGS) -o $@ ClientMain.c Client.c Stream.c
 
 run_client: client
 	./client 127.0.0.1

+ 29 - 18
Server.c

@@ -154,16 +154,16 @@ void* clientHandler(void* data)
     Server* s = ((ThreadData*) data)->server;
     
     Stream in;
-    while(strcmp(in.data, "quit") != 0)
+    while(1)
     {
-        int size = recv(s->clientSockets[id], in.data, BUFFER_SIZE - 1, 0);
+        streamInit(&in);
+        int size = recv(s->clientSockets[id], in.data, in.size, 0);
         if(size > 0)
         {
-            in.data[size] = '\0';
             int package = ((int) in.data[0]);
             if(package >= 0 && package < s->hIndex)
             {
-                printf("Received package %d from %d: %s\n", package, id, in.data);
+                printf("Received package %d from %d\n", package, id);
                 in.index = 1;
                 in.size = size;
                 s->handlers[package](&in);
@@ -199,11 +199,19 @@ void* clientHandler(void* data)
     return NULL;
 }
 
+int serverSend(int clientSocket, Stream* out)
+{
+    if(send(clientSocket, out->data, out->index, 0) == -1)
+    {
+        perror("Cannot send data");
+        return -1;
+    }
+    return 0;
+}
+
 void serverWaitForConnection(Server* s)
 {
     socklen_t addrlen = sizeof(struct sockaddr_in);
-    char buffer[BUFFER_SIZE];
-    
     while(1)
     {
         printf("Waiting for connections...\n");
@@ -231,19 +239,22 @@ void serverWaitForConnection(Server* s)
                     {
                         perror("Cannot create thread");  
                         
-                        strcpy(buffer, "error: cannot create thread\n");
-                        if(send(clientSocket, buffer, strlen(buffer), 0) == -1)
-                        {
-                            perror("Cannot send error");
-                        }
+                        Stream out;
+                        streamInit(&out);
+                        streamWriteChar(&out, -1);
+                        streamWriteChars(&out, "Cannot create thread\n");
+                        serverSend(clientSocket, &out);
                         close(clientSocket);
                     }
                     else
                     {
                         s->clientSockets[i] = clientSocket;
                         
-                        strcpy(buffer, "Welcome to server, please enter your command:\n");
-                        if(send(clientSocket, buffer, strlen(buffer), 0) == -1)
+                        Stream out;
+                        streamInit(&out);
+                        streamWriteChar(&out, 1);
+                        streamWriteChars(&out, "Welcome to the server, please enter your command:\n");
+                        if(serverSend(clientSocket, &out) == -1)
                         {
                             perror("Cannot send welcome message");
                             close(clientSocket);
@@ -258,11 +269,11 @@ void serverWaitForConnection(Server* s)
                 {
                     printf("max clients reached\n");    
                     
-                    strcpy(buffer, "error: max clients reached\n");
-                    if(send(clientSocket, buffer, strlen(buffer), 0) == -1)
-                    {
-                        perror("Cannot send error");
-                    }
+                    Stream out;
+                    streamInit(&out);
+                    streamWriteChar(&out, -1);
+                    streamWriteChars(&out, "the server is full\n");
+                    serverSend(clientSocket, &out);
                     close(clientSocket);
                     break;
                 }

+ 1 - 0
Server.h

@@ -27,6 +27,7 @@ void serverInitDefaults(Server* s);
 int serverInit(Server* s, int maxClients, short port);
 void serverRemove(Server* s);
 
+int serverSend(int clientSocket, Stream* out); 
 void serverWaitForConnection(Server* s);
 
 void serverRegisterHandler(Server* s, StreamFunction f);

+ 26 - 12
ServerMain.c

@@ -12,24 +12,38 @@ void interruptHandler(int signal)
     exit(EXIT_SUCCESS);
 }
 
-void test(Stream* in)
+void package0(Stream* in)
 {
     int i;
-    while(streamGetInt(&i, in) != -1)
+    if(streamGetInt(in, &i) != -1)
     {
-        printf("%d  ", i);
+        printf("first number: %d\n", i);
+    }
+    else
+    {
+        printf("first number: ---\n");
+    }
+    
+    if(streamGetInt(in, &i) != -1)
+    {
+       printf("second number: %d\n", i);
+    }
+    else
+    {
+        printf("second number: ---\n");
     }
-    printf(" HALLO\n");
 }
 
-void test2(Stream* in)
+void package1(Stream* in)
 {
-    printf("HALLO2\n");
+    char buffer[128];
+    streamGetChars(in, buffer, 128);
+    printf("%s\n", buffer);
 }
 
-void test3(Stream* in)
+void package2(Stream* in)
 {
-    printf("HALLO3\n");
+    printf("I'm not containing any data.\n");
 }
 
 int main()
@@ -39,14 +53,14 @@ int main()
     signal(SIGINT, interruptHandler);
     signal(SIGKILL, interruptHandler);
     
-    if(serverInit(&server, 3, 6543))
+    if(serverInit(&server, 3, 6543) == -1)
     {
         return EXIT_FAILURE;
     }
     
-    serverRegisterHandler(&server, test);
-    serverRegisterHandler(&server, test2);
-    serverRegisterHandler(&server, test3);
+    serverRegisterHandler(&server, package0);
+    serverRegisterHandler(&server, package1);
+    serverRegisterHandler(&server, package2);
     
     serverWaitForConnection(&server);
     

+ 62 - 19
Stream.c

@@ -1,6 +1,13 @@
 #include "Stream.h"
+#include <stdlib.h>
 
-int streamGetChar(char* c, Stream* in)
+void streamInit(Stream* s)
+{
+    s->index = 0;
+    s->size = BUFFER_SIZE;
+}
+
+int streamGetChar(Stream* in, char* c)
 {
     if(in->index < in->size)
     {
@@ -11,7 +18,29 @@ int streamGetChar(char* c, Stream* in)
     return -1;
 }
 
-int streamGetShort(short* s, Stream* in)
+int streamGetChars(Stream* in, char* buffer, int length)
+{
+    int index = 0;
+    length--;
+    while(index < length)
+    {
+        char c;
+        if(streamGetChar(in, &c) == -1)
+        {
+            buffer[index] = '\0';
+            return index;
+        }
+        else
+        {
+            buffer[index] = c;
+        }
+        index++;
+    }
+    buffer[index] = '\0';
+    return index;
+}
+
+int streamGetShort(Stream* in, short* s)
 {
     if(in->index + 1 < in->size)
     {
@@ -22,7 +51,7 @@ int streamGetShort(short* s, Stream* in)
     return -1;
 }
 
-int streamGetInt(int* i, Stream* in)
+int streamGetInt(Stream* in, int* i)
 {
     if(in->index + 3 < in->size)
     {
@@ -34,38 +63,52 @@ int streamGetInt(int* i, Stream* in)
     return -1;
 }
 
-int streamWriteChar(char c, Stream* in)
+int streamWriteChar(Stream* out, char c)
 {
-    if(in->index < in->size)
+    if(out->index < out->size)
     {
-        in->data[in->index] = c;
-        in->index++;
+        out->data[out->index] = c;
+        out->index++;
         return 0;
     }
     return -1;
 }
 
-int streamWriteShort(short s, Stream* in)
+int streamWriteChars(Stream* out, char* c)
 {
-    if(in->index + 1 < in->size)
+    int i = 0;
+    while(c[i] != '\0')
     {
-        in->data[in->index] = s & 0xFF;
-        in->data[in->index + 1] = (s >> 8) & 0xFF;
-        in->index += 2;
+        if(streamWriteChar(out, c[i]) == -1)
+        {
+            return -1;
+        }
+        i++;
+    }
+    return 0;
+}
+
+int streamWriteShort(Stream* out, short s)
+{
+    if(out->index + 1 < out->size)
+    {
+        out->data[out->index] = s & 0xFF;
+        out->data[out->index + 1] = (s >> 8) & 0xFF;
+        out->index += 2;
         return 0;
     }
     return -1;
 }
 
-int streamWriteInt(int i, Stream* in)
+int streamWriteInt(Stream* out, int i)
 {
-    if(in->index + 3 < in->size)
+    if(out->index + 3 < out->size)
     {
-        in->data[in->index] = i & 0xFF;
-        in->data[in->index + 1] = (i >> 8) & 0xFF;
-        in->data[in->index + 2] = (i >> 16) & 0xFF;
-        in->data[in->index + 3] = (i >> 24) & 0xFF;
-        in->index += 4;
+        out->data[out->index] = i & 0xFF;
+        out->data[out->index + 1] = (i >> 8) & 0xFF;
+        out->data[out->index + 2] = (i >> 16) & 0xFF;
+        out->data[out->index + 3] = (i >> 24) & 0xFF;
+        out->index += 4;
         return 0;
     }
     return -1;

+ 10 - 6
Stream.h

@@ -10,15 +10,19 @@ typedef struct Stream
     char data[BUFFER_SIZE];
 } Stream;
 
+void streamInit(Stream* s);
+
 typedef void (*StreamFunction) (Stream*);
 
-int streamGetChar(char* c, Stream* in);
-int streamGetShort(short* s, Stream* in);
-int streamGetInt(int* i, Stream* in);
+int streamGetChar(Stream* in, char* c);
+int streamGetChars(Stream* in, char* buffer, int length);
+int streamGetShort(Stream* in, short* s);
+int streamGetInt(Stream* in, int* i);
 
-int streamWriteChar(char c, Stream* in);
-int streamWriteShort(short s, Stream* in);
-int streamWriteInt(int i, Stream* in);
+int streamWriteChar(Stream* out, char c);
+int streamWriteChars(Stream* out, char* c);
+int streamWriteShort(Stream* out, short s);
+int streamWriteInt(Stream* out, int i);
 
 #endif
 

+ 0 - 120
client.c

@@ -1,120 +0,0 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#define __USE_MISC
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-
-#include "Stream.h"
-
-#define BUFFER_SIZE 1024
-#define PORT 6543
-
-int clientSocket = -1;
-
-void cleanUp()
-{
-    if(clientSocket != -1)
-    {
-        if(close(clientSocket) != 0)
-        {
-            perror("Cannot close client socket");
-        }
-        else
-        {
-            printf("socket closed\n");
-        }
-    }
-}
-
-void interruptHandler(int signal)
-{
-    cleanUp();
-    exit(EXIT_SUCCESS);
-}
-
-void safeExit(int status)
-{
-    cleanUp();
-    exit(status);
-}
-
-int main(int argc, char **argv)
-{
-    signal(SIGINT, interruptHandler);
-    signal(SIGKILL, interruptHandler);
-
-    char buffer[BUFFER_SIZE];
-    int size;
-
-    if(argc < 2)
-    {
-        printf("Usage: %s server_address\n", argv[0]);
-        safeExit(EXIT_FAILURE);
-    }
-
-    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
-    if(clientSocket == -1)
-    {
-        perror("Cannot create socket");
-        safeExit(EXIT_FAILURE);
-    }
-
-    struct sockaddr_in clientSocketData;
-    memset(&clientSocketData, 0, sizeof (clientSocketData));
-    clientSocketData.sin_family = AF_INET;
-    clientSocketData.sin_port = htons(PORT);
-    if(inet_aton(argv[1], &clientSocketData.sin_addr) == 0)
-    {
-        printf("'%s' is not a valid ip\n", argv[1]);
-        safeExit(EXIT_FAILURE);
-    }
-
-    if(connect(clientSocket, (struct sockaddr*) &clientSocketData, sizeof(clientSocketData)) == 0)
-    {
-        printf("Connection with server (%s) established\n", inet_ntoa(clientSocketData.sin_addr));
-        size = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);
-        if(size > 0)
-        {
-            buffer[size] = '\0';
-            printf("%s", buffer);
-            if(strncmp(buffer, "error", 5) == 0)
-            {
-                safeExit(EXIT_FAILURE);
-            }
-        }
-    }
-    else
-    {
-        perror("No server is available");
-        safeExit(EXIT_FAILURE);
-    }
-
-    while(strcmp(buffer, "quit\n") != 0)
-    {
-        printf("Send message: ");
-        fgets(buffer, BUFFER_SIZE, stdin);
-        
-        Stream out;
-        out.index = 0;
-        out.size = BUFFER_SIZE;
-        streamWriteChar(0, &out);
-        streamWriteInt(-423, &out);
-        streamWriteInt(-6456463, &out);
-        streamWriteInt(443534, &out);
-        streamWriteInt(75676, &out);
-        
-        if(send(clientSocket, out.data, out.index, MSG_NOSIGNAL) == -1)
-        {
-            perror("Cannot send data");
-            break;
-        }
-    }
-    
-    safeExit(EXIT_SUCCESS);
-    return EXIT_SUCCESS;
-}