0

我正在模拟客户端-服务器套接字事务。假设,客户端发送了一些 ip 数据包

status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
                    0);

sock套接字在哪里,packet指向一个 ip 数据包(带有 ip header structiphdr和 tcp header struct tcphdr

现在,在服务器端,我想使用一些函数来检索数据packet并显示它。客户端和服务器之间的连接已正确设置,但在尝试使用该recv功能时,我没有得到任何数据。是recv正确的功能

所以在客户端我有

packet = malloc(sizeof(struct iphdr)+ sizeof(struct tcphdr));

我用

send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
                    0);

在服务器端,我声明了一些char packet[32];并使用了这个

recv(sock, packet, 32, 0);

编辑 2 - 这是代码

在客户端

在客户端编辑(为了缩短,我没有提到包含的库,struct iphdrtcphdrin_chksum function,以及我没有水合 tcp 标头,现在我只想测试)

struct tcphdr tcp_hdr;
struct ip ip_hdr;
#define PORT 23

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

struct ip * ip = (struct ip *)malloc(sizeof(struct ip));
struct tcphdr * tcp;
char * packet;
int sock_err;
int psize=0, status = 1;

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


ip->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + psize);
ip->ip_hl = 5;
ip->ip_v = 4;
ip->ip_ttl = 255;
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_p = IPPROTO_ICMP;
ip->ip_src.s_addr = inet_addr("127.0.0.1");
ip->ip_dst.s_addr = inet_addr("127.0.0.1");
ip->ip_sum = in_chksum((u_short *)ip, sizeof(struct ip));



        status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
                0);

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


    if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
                printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));

sendmeifyoucan(sock, &sin,size);
                /* Si l'on reçoit des informations : on les affiche à l'écran */
                            }

    }


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

编辑 3 - 标题

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;

#include <stdio.h>
#include <stdlib.h>
#define PORT 23
4

1 回答 1

0

好的,现在我看到了你的问题。

在客户端:

第一期(大):

你根本没有连接。

connect()在客户端的电话在哪里?

如果你想使用 SOCK_STREAM 你需要一个 connect(2) 调用

在代码片段中:

     if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) {
        printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));

        /* Si l'on reçoit des informations : on les affiche à l'écran */
                    }

您的 sendmeifyoucan() 在 if 块之外{ }

第二期

    struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr *));

应该

    struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr));

否则你会遇到堆栈溢出问题。

第三期(不大)

你正在分配char *packet,但你没有将任何东西复制到它上面,它只是 memset 为 0;

相应地调试并重试:)

于 2013-06-17T13:05:31.903 回答