1

我对套接字编程很陌生,我想模拟一个客户端-服务器事务。因此,对于我的客户端发送的数据包,我声明 a sock = socket(AF_INET, SOCK_STREAM, 0), a SOCKADDR_IN sin,我通过绑定它们bind(sock, (SOCKADDR*) &sin, sizeof(sin)),然后,在声明一个经典的structip 标头并为 a 分配一些内存后struct iphdr * ip,我最终通过 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

这似乎有效。但是现在,我想跟踪发送的数据包,所以我使用服务器端文件再次声明a sock,我声明aSOCKADDR_IN client_sin我接受客户端的连接accept(sock, (SOCKADDR*)&client_sin, &recsize);,但似乎没有收到我的数据包?我用它recv(sock, buffer, 32, 0) != SOCKET_ERROR来捕获数据包,(当然我在客户端之前启动了服务器程序)。完全错了吗?

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;
    }

在服务器端编辑

#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;
}
4

1 回答 1

1

您不能sendtoSOCK_STREAM套接字一起使用。使用connectandsend或者write代替。

此外,您通常不使用struct iphdr并且struct tcphdr在正常的套接字编程中,这些仅用于原始 ip 数据包(哪些套接字不是)。

于 2013-06-14T12:29:57.980 回答