-1

I have to type two strings in a client and send them with a struct to server. Then the server does c = a + b and sends a news struct with { a, b, c } to client. If a or b received is quit, server sends to client bye.

Client receives the struct and prints c. If it is bye it closes connection, else it returns to asking the input of a and b and the cycle begins again.

Client:

    #if defined WIN32
    #include <Winsock2.h>
    #else
    #define closesocket close
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define BUFSIZE 30

    void ClearWinSock() {
    #if defined WIN32
        WSACleanup();
    #endif
    }

    //-----------------------------INIZIALIZZAZIONE WSADATA

    int main (void) {
    #if defined WIN32

        WSADATA wsaData;
        int iResult = WSAStartup (MAKEWORD (2,2), &wsaData);

        if (iResult !=0) {
            printf ("error at WSASturtup\n");
            return 0;
            }

    #endif

    //--------------------------------CREAZIONE SOCKET

        int Csocket;

        Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);

        if (Csocket < 0) {

        printf ("socket creation failed");
        closesocket (Csocket);
        ClearWinSock();
        return 0;
        }

        char s_address[BUFSIZE];
                printf ("Inserisci l'indirizzo dell'host a cui connetterti\n");
                scanf ("%s", s_address);

                int port;
                printf ("Inserisci la porta a cui connetterti\n");
                scanf("%d", &port);

                struct sockaddr_in sad;
                    memset (&sad, 0, sizeof(sad));
                    sad.sin_family = AF_INET;
                    sad.sin_addr.s_addr = inet_addr(s_address);
                    sad.sin_port = htons (port);

    //------------------------------CONNESSIONE AL SERVER

       if (connect(Csocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
            printf ("failed to connect\n");
            closesocket (Csocket);
            ClearWinSock();
            return 0;
       }

    //-----------------------------RICEZIONE STRINGA DAL SERVER

       char buf[BUFSIZE];

       int read = recv (Csocket, buf, BUFSIZE - 1, 0);

       if (read <=0) {

        printf ("Qualcosa non và!\n");
       }

       else {
        buf[read] = '\0';  //tappo stringa per sicurezza
        printf("Server scrive: %s\n", buf);
       }


    //------------------------------STRUTTURA DI STRINGHE

         struct stringab {
                                char a[30];
                                char b[30];
                                char c[70];
                            } ab;


                            void* abptr = &ab;


                printf ("Inserisci prima stringa\n");
                scanf ("%s", ab.a);


                            printf ("Inserisci seconda stringa\n");
                            scanf ("%s", ab.b);



        if (send(Csocket, (char*)abptr, sizeof(ab), 0) != sizeof(ab)) {
               printf("client-send() sent a different number of bytes than expected");
               closesocket(Csocket);
               ClearWinSock();
               system ("pause");
               return 0;
           }

 printf ("\n");
   closesocket (Csocket);
   system ("pause");
   ClearWinSock();
   return 0;

   }

Server:

#if defined WIN32
#include <Winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 30

void ClearWinSock() {
#if defined WIN32
    WSACleanup();
#endif
}

int main(void) {

//---------------------------INIZIALIZZAZIONE WSADATA

#if defined WIN32

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf ("Error at WSAStartup");
        return 0;
    }

#endif

//-------------------------------CREAZIONE SOCKET

    int Mysocket;
    Mysocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    //Valutare la presenza di errori per assicurarsi che la socket sia valida.
    if (Mysocket < 0) {
        printf("socket creation failed\n");
        return 0;
    }

    //Assegnazione indirizzo alla socket.
    struct sockaddr_in sad;
    memset(&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr ("127.0.0.1");
    sad.sin_port = htons (9888);

//------------------------ASSEGNAZIONE PORTA E IP ALLA SOCKET

if (bind(Mysocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
    printf ("bind() failed\n");
    closesocket(Mysocket);
    return 0;
}

//---------------------------SETTAGGIO SOCKET ALL'ASCOLTO

int qlen = 10; //numero client che il server può gestire

if (listen (Mysocket, qlen) < 0) {

    printf("listen() failed\n");
    closesocket(Mysocket);
    return 0;
}

struct sockaddr_in cad;  // struttura per l'indirizzo del cient
int Csocket;             // descrittore socket per il client
int clientlen;           // lunghezza indirizzo del client

//------------------------------ACCETTA LA CONNESSIONE

while (1) {

    printf("In attesa di un client con cui comunicare...\n");
    memset(&cad, 0, sizeof(cad));
    clientlen = sizeof(cad);       // assegna la dimensione dell'indirizzo del client

    if((Csocket = accept(Mysocket, (struct sockaddr*) &cad, &clientlen)) < 0) {
        printf ("accept failed\n");
        closesocket(Mysocket);
        ClearWinSock();
        return 0;
    }


    printf("Connessione stabilita con il client il cui indirizzo e' %s \n\n", inet_ntoa(cad.sin_addr));

//---------------------------------------INVIO STRINGA AL CLIENT

    char* inputString = "Connessione avvenuta!";
    int stringlen = strlen(inputString);


    if (send(Csocket, inputString, stringlen, 0) != stringlen) {
        printf("client-send() sent a different number of bytes than expected");
        closesocket(Csocket);
        ClearWinSock();
        system ("pause");
        return 0;
    }

printf ("\n");
closesocket (Csocket);
system ("pause");
ClearWinSock();
return 0;

}

So, did I send the struct to server in this manner? How the server could recv() this struct and do c = a + b re-building and re-sending the struct?

skink
  • 5,133
  • 6
  • 37
  • 58
mark
  • 5
  • 3
  • 1
    Did you get any errors from sending it? Did you receive the structure intact on the other side? Can you please elaborate on the problem you have? And please [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask), and learn how to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). You should probably also read [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) by Eric Lippert. – Some programmer dude Oct 24 '17 at 15:39
  • 2
    Of topic (I think): Be careful about sending structs over the network in this way. If the client and server are different types, their programs compiled by different compilers, etc. it may go very wrong. In most cases you at least want a packed struct to avoid different layout. – Support Ukraine Oct 24 '17 at 15:46
  • I launched the code and the typing of two strings works. It seems no error on the send side; but I don't know how to receive the struct on the server side so I don't know if it is receiving with no problems. – mark Oct 24 '17 at 15:47
  • also remember that TCP is a streaming protocol. You can send 100 bytes in one send but might receive 5 20 byte messages at the other end. YOu must loop receiving till you know you have received everything – pm100 Oct 24 '17 at 15:48
  • Have you tried an internet search (e.g. google) for `c socket recv stackoverflow` ? I got multiple hits and feel confident that some of those links will help you - example: https://stackoverflow.com/questions/30655002/socket-programming-recv-is-not-receiving-data-correctly – Support Ukraine Oct 24 '17 at 15:50
  • For network issues I always recommend using netcat and a packet sniffer. Netcat takes the place of the client/server with a known working module, and a packet sniffer lets you see exactly what you're sending. Both of these reduce variables where problems could be and let you focus on one thing at a time. – yano Oct 24 '17 at 16:02
  • Yes I have already tried the search on stackoverflow and I managed to do this piece of code (the client-send side) thanks to it, now I wish to understand how to receive the struct on the server side. I have no problems sending strings, but never did this with structs. – mark Oct 24 '17 at 16:04
  • Welcome to Stack Overflow! Your code is incomplete; in particular, it seems to be missing a `main()` function and at least one `#include`. Please [edit] your code so it's a [mcve] of your problem, then we can try to reproduce and solve it. You should also read [ask]. – Toby Speight Oct 24 '17 at 16:18
  • Edited. Sorry, I have some physical difficulties. – mark Oct 24 '17 at 16:29
  • 1
    I solved the problem. Can I edit post to make it useful for other users? – mark Oct 25 '17 at 15:08
  • It would be good if you posted your solution, but not as an edit to the question, but as an answer. – Armali Oct 26 '17 at 12:35

1 Answers1

0

I solved the problem on send side and receive side like this:

send(Csocket, (char*)abptr, sizeof(ab), 0);

recv (Csocket, (char*)abptr, sizeof(ab), 0);

So I passed the struct with a struct pointer on both side. I think it's a good solution in local hosting, maybe you need a better one for net (security reasons).

mark
  • 5
  • 3