0

このコードは、txtファイルを完全に送信および受信しますが、.exeや.imgなどのその他の形式には送信できません。htonlまたはhtonsを使用する必要があるので、これらを手伝ってください。見てください!

これがサーバー側のrecv関数です::

 if (socket_type != SOCK_DGRAM)
        {

                fi = fopen (final,"wb");
                retval = recv(msgsock, recv_buf, strlen(recv_buf), 0);
                /*recv_buf[retval] = '\0';
                fprintf (fi,"%s",recv_buf);*/

                int i;
                i=atoi(recv_buf);
                char *q;
                q=(char *)malloc(i*sizeof(char));
                retval = recv(msgsock, q, strlen(q), 0);
                //printf ("%s",q);
                fwrite(q,i,1,fi);
                fclose(fi);

        }
        else
        {
            retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen);
            printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr));
            printf ("SOCK_DGRAM");
        }

        if (retval == SOCKET_ERROR)
        {
            fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError());
            closesocket(msgsock);
            //continue;
        }
        else
            printf("Server: recv() is OK.\n");

        if (retval == 0)
        {
            printf("Server: Client closed connection.\n");
            closesocket(msgsock);
                //continue;
        }
        printf("Server: Received %d bytes, data from client\n", retval);

The client side sending function :::

void send_command()
{
    int bytesent;
    FILE *file_out;
    //file_out = fopen(file_path,"rb");
    char str_all[100000];//flag [30]="end";

    ///////////////////////getsize//////////////
    char fsize[5];
    int filesize;
    file_out = fopen(file_path, "rb");
    fseek(file_out, 0, SEEK_END);
    filesize = ftell(file_out);
    rewind (file_out);
    itoa (filesize,fsize,10);
    /////////////////////////////////////////////
    send (ConnectSocket, fsize, strlen (fsize), 0);

    char *r = (char *)malloc (filesize * sizeof(char));

    fread(r,filesize,1,file_out);
    bytesent = send( ConnectSocket, r, strlen(r), 0 );
    printf("\nClient: Bytes sent: %ld\n", bytesent);
    fclose (file_out);

    /*while (fscanf(file_out,"%s",&str_all) != EOF)
    {
        bytesent = send( ConnectSocket, str_all, strlen(str_all), 0 );
        printf("\nClient: Bytes sent: %ld\n", bytesent);
        //Sleep(500);
    }*/

    /*printf("%s",flag);
    send( ConnectSocket, flag, strlen(flag), 0 );*/
    WSACleanup();
    //return 0;
    }
4

2 に答える 2

2

OK、あなたのプログラムには複数の問題があります。

  • バイナリ データを転送しています。受信者は一連のバイトのみを確認します。charのすべての可能な値は正当なデータ値であるため、受信者がデータの終わりを知る方法はありません。テキストデータを送信する場合、a0はデータの終わりを意味すると言えますが、今はできません。そのため、サーバーとクライアント間の「プロトコル」を決定する必要があります。最も簡単なのは、サーバーが最初の 4 バイトでデータの長さを送信することです (ntonl()これntohl()を移植可能に行う方法については、こちらを参照してください)。次に、受信者は読み取るバイト数を正確に認識します。
  • レシーバ バッファを として宣言し、char *recv_buf同様に を宣言しrecv_buf1ます。2 つのポインターのいずれにもストレージを割り当てないため、有用な場所を指していません。次に、あなたのrecv呼び出しは次のとおりです。recv(msgsock, recv_buf, sizeof(recv_buf), 0); これにも問題があります。1 つ目は、上記のものです: のストレージがありませんrecv_buf2 つ目は、 にストレージを割り当てた後、バッファポイントrecv_bufの長さではなく、char ポインタのサイズを取得していることです。recv両方の問題を解決する簡単な方法の 1 つは、次のように宣言recv_bufして呼び出しでchar recv_buf[SIZE];使用することです。sizeof recv_bufrecv()

私はあなたのコードの残りの部分を見ていません。おそらく、適切な C およびネットワーク プログラミングの入門書が必要です。

于 2010-01-21T07:15:37.933 に答える
1

C文字列のnull終了と、ソケットで送信されたパケットの終わりを混同していると思います。パケットの「終了」はなく、単なるバイトの文字列です。ゼロは完全に合法であり、長さを明示的に渡す(そして受け取る)。確かに、複数のパケットを受信するために帯域外機能を使用する必要はありません。何を求めているのか、具体的に教えてください。

于 2010-01-20T22:22:50.577 に答える