recv() 函数用于在一个字符串中获取 while 缓冲区的标志 [windows C]

发布于 2024-08-18 13:16:22 字数 2540 浏览 9 评论 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;
    }

This code sends and recv s txt file perfectly but cannot do it to otehr formats like .exe or .img. Please help me with these as I need to use htonl or htons??
Take a look!!

Here is the server side recv function ::

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴我老 2024-08-25 13:16:22

好的,您的程序存在多个问题。

  • 您正在传输二进制数据。接收者只会看到一个字节序列。接收方无法知道数据的结尾,因为 char 的所有可能值都是合法的数据值。如果您发送文本数据,您可以说 0 表示数据结束,但现在不能。因此,您必须决定服务器和客户端之间的“协议” - 最简单的是服务器发送前 4 个字节中的数据长度(在 ntonl() 上读取并ntohl() 了解如何可移植地执行此操作)。然后,接收方将确切地知道要读取多少字节。
  • 您将接收缓冲区声明为 char *recv_buf,对于 recv_buf1 也是如此。您没有为两个指针中的任何一个分配任何存储空间,因此它们没有指向任何有用的地方。然后,您的 recv 调用是: recv(msgsock, recv_buf, sizeof(recv_buf), 0); 这也有问题。第一个是上面提到的:您没有用于 recv_buf 的存储空间。第二个是,在为 recv_buf 分配存储空间之后,您将获取 char 指针的大小,而不是缓冲区 recv 的长度指向.解决这两个问题的一种简单方法是将 recv_buf 声明为:char recv_buf[SIZE];,然后在 recv_buf 中使用 sizeof recv_buf代码>recv() 调用。

我没有看过你其余的代码。您可能需要良好的 C 和网络编程介绍。

OK, there are multiple issues with your program.

  • You are transferring binary data. The receiver is only going to see a sequence of bytes. There is no way for the receiver to know the end of the data, since all possible values of char are legal data values. If you were sending text data, you could say that a 0 signifies the end of the data, but now you can't. So, you have to decide on a "protocol" between the server and the client—the simplest is that the server sends the length of the data in the first 4 bytes (read up on ntonl() and ntohl() for how to do this portably). Then, the receiver will know exactly how many bytes to read.
  • You declare the receiver buffer as char *recv_buf, and similarly for recv_buf1. You don't allocate any storage for any of the two pointers, so they aren't pointing to anywhere useful. Then, your recv call is: recv(msgsock, recv_buf, sizeof(recv_buf), 0); This also has problems. The first is the one mentioned above: you don't have storage for recv_buf. The second is that after you do allocate storage for recv_buf, you are taking the size of a char pointer instead of the length of the buffer recv points to. One easy way to solve both the issues would be to declare recv_buf as: char recv_buf[SIZE]; and then use sizeof recv_buf in the recv() call.

I haven't looked at the rest of your code. You probably need a good C and network programming introduction.

峩卟喜欢 2024-08-25 13:16:22

我认为您将 C 字符串的空终止与套接字上发送的数据包的结尾混淆了。数据包没有“终止”,它只是一串字节。零是完全合法的,并且您明确地传递(和接收)长度。您当然不需要使用带外设施来接收多个数据包。您能更具体地说明您要问的内容吗?

I think you're confusing the null-termination of a C string with the end of a packet sent on a socket. There is no "termination" of a packet, it's just a string of bytes. Zeros are completely legal, and you pass (and receive) the length explicitly. You certainly don't need to use the out-of-band facilities to receive multiple packets. Can you be more specific about what you're asking?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文