1
votes

I am very new to socket programming, I want to simulate a client-server transaction. So for my client sent packet, I declare a sock = socket(AF_INET, SOCK_STREAM, 0), a SOCKADDR_IN sin, I bind them through bind(sock, (SOCKADDR*) &sin, sizeof(sin)), then, after declaring a classic struct ip header, and hydrating a allocating some memory to struct iphdr * ip, I finally send the packet via ip

sent_packet = sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
                    0, (struct sockaddr *) sin, sizeof(struct sockaddr));//sent_packet is an int, I use also a TCP header struct, packet is the pointer that stores the ip and tcp data

This seems to work. But now, I want to trace the sent packet, so I use a server side file to declare again a sock, I declare a SOCKADDR_IN client_sin I accept the connection of the client via accept(sock, (SOCKADDR*)&client_sin, &recsize);, but it seems that my packet is not received ? I use for that recv(sock, buffer, 32, 0) != SOCKET_ERROR to catch the packets, (of course I launched the server program before the client one). Am going completely wrong ?

Edit on the client side (to shorten, I didn't mention the included libraries, the `struct` `iphdr`, `tcphdr`, the `in_chksum function`, as well I didn't hydrate the tcp header, for now I just want to test)



#define PORT 23

    int sendmeifyoucan(SOCKET sock, SOCKADDR_IN * sin , int size ){

        struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr *));
        struct tcphdr * tcp;
        char * packet;
        int psize=0, status = 1;
        printf("%d I am lost in the web ",status);

        packet = malloc(sizeof(struct iphdr)+ sizeof(struct tcphdr));
        memset(packet, 0, sizeof(struct iphdr) + sizeof(struct tcphdr));

        sin->sin_addr.s_addr = inet_addr("127.0.0.1");
        ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + psize);
        ip->ihl = 5;
        ip->version = 4;
        ip->ttl = 255;
        ip->tos = 0;
        ip->frag_off = 0;
        ip->protocol = IPPROTO_ICMP;
        ip->saddr = sin->sin_addr.s_addr;
        ip->daddr = sin->sin_addr.s_addr;
        ip->check = in_chksum((u_short *)ip, sizeof(struct iphdr));

        status = sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
                        0, (struct sockaddr *) sin, sizeof(struct sockaddr));

        free(packet);

        return 0;
    }


    int main(void)
    {

        int erreur = 0;

        SOCKADDR_IN sin;
        SOCKET sock;

        SOCKADDR_IN csin;
        SOCKET csock;

        int sock_err;


        if(!erreur)
        {
            sock = socket(AF_INET, SOCK_STREAM, 0);

            if(sock != INVALID_SOCKET)
            {
                printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
                int size = 0;
                /* Configuration */
                sin.sin_addr.s_addr = inet_addr("127.0.0.1"); 
                sin.sin_family = AF_INET;                
                sin.sin_port = htons(PORT);
                /* Listage du port */

                    sendmeifyoucan(sock, &sin,size);

                printf("Fermeture de la socket client\n");
                closesocket(csock);
                printf("Fermeture de la socket serveur\n");
                closesocket(sock);
                printf("Fermeture du serveur terminée\n");
            }
            else
                perror("socket");

        }

        return EXIT_SUCCESS;
    }

Edit on the server side

#define PORT 23
int main(void)
{

    int erreur = 0;
    SOCKET sock;

    SOCKADDR_IN sin;
    socklen_t recsize = sizeof(sin);
    SOCKADDR_IN csin;
    char buffer[32] = "";

    int sock_err;


    if(!erreur)
    {
        sock = socket(AF_INET, SOCK_STREAM, 0);

        if(sock != INVALID_SOCKET)
        {
            printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
            /* Configuration */
            csin.sin_addr.s_addr = inet_addr("127.0.0.1"); 
            csin.sin_family = AF_INET;                 
            csin.sin_port = htons(PORT);
            sock_err = bind(sock, (SOCKADDR*) &csin, sizeof(csin));

            if(sock_err != SOCKET_ERROR)
            {
                sock_err = listen(sock, 5);
                printf("Listage du port %d...\n", PORT);
            }


            if(sock_err != SOCKET_ERROR)
            {
                /* Attente pendant laquelle le client se connecte */
                printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);

                sock = accept(sock, (SOCKADDR*)&sin, &recsize);
            }

            if(recv(sock, buffer, 32, 0) != SOCKET_ERROR)
            {
                    printf("Recu : %s\n", buffer);
            }
            else
            {
                printf("Impossible de se connecter\n");
            }

            closesocket(sock);
        }
        else
            perror("socket");

    }

    return EXIT_SUCCESS;
}
1
@nos I have edited my postepsilones
@nos oh yes sure I missed that, (btw I am using Xcode on osx)epsilones
@nos so I edited my post, in fact it seems the function recv(sock, buffer, 32, 0) is never executed. I thought, that when the sendto function is processed, the accepted connection could deliver the data to the recv function. Am I missing something ?epsilones

1 Answers

1
votes

You can't use sendto with a SOCK_STREAM socket. Use connect and either send or write instead.

Also, you usually don't use struct iphdr and struct tcphdr in normal socket programming, those are only used with raw ip packets (which sockets aren't).