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 iphdr、tcpヘッダーをハイドレートしませんでした。今のところ、テストしたいだけです)tcphdrin_chksum function

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 ブロックの外側にあります{ }

2号

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

する必要があります

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

そうしないと、スタック オーバーフローの問題が発生します。

3番目の問題(それほど大きくない)

割り当てchar *packetていますが、何もコピーしていません。memset が 0 になっているだけです。

それに応じてデバッグし、再試行してください:)

于 2013-06-17T13:05:31.903 に答える