【问题标题】:First send by socket the size of the file I want to send首先通过套接字发送我要发送的文件的大小
【发布时间】:2014-06-19 14:25:11
【问题描述】:

我想向 program2 发送一个文件,但首先我想发送该文件的大小。 我在 program1 中有这个:

FILE *script;
int j;
int size;
char* codigo;
if (argc > 1){
  for (j = 1; j < argc; j++){
    if ((script = fopen(argv[j], "r")) == NULL){
        perror(argv[j]);
    }else{
        fseek(script, 0, SEEK_END);
        size = ftell(script); 
        fseek(script, 0, SEEK_SET); 
        codigo = malloc(sizeof(char)*(size +1));
            if(codigo) { 
            fread(codigo, sizeof(char), size, script);
                codigo[size] = '\0';
            }
            struct addrinfo hints;
                struct addrinfo *serverInfo;

                memset(&hints, 0, sizeof(hints));
                hints.ai_family = AF_UNSPEC; 
                hints.ai_socktype = SOCK_STREAM;

                getaddrinfo(ip, puerto, &hints, &serverInfo);


                int serverSocket;
                serverSocket = socket(serverInfo->ai_family, serverInfo->ai_socktype, serverInfo->ai_protocol);

                connect(serverSocket, serverInfo->ai_addr, serverInfo->ai_addrlen);
                freeaddrinfo(serverInfo);  

                printf("Conectado al servidor\n");
                send(serverSocket, codigo, strlen(codigo) + 1, 0);
                close(serverSocket);
    }
    fclose(script);
    free(codigo);
    free(ip);
    free(puerto);
  }
}

program1 中,我将脚本的内容发送到 program2。在 program2 我有:

#define PACKAGESIZE 100

我为recv 定义了这个包,但是这个包大小可以是可变的,所以我需要program1 发送我之后发送的包的大小。 在 program2 中,当我有尺寸时,我可以接收包装并打印它。

【问题讨论】:

  • 你想怎么发送?这是您定义的协议。
  • 我想发送文件的大小。我想是 IPV4 我问我。

标签: c sockets int send sizeof


【解决方案1】:

使用固定大小的整数作为文件大小,这样双方就知道要交换多少字节来换取文件大小。 send() 首先是大小,然后是 send() 需要的数据。另一方面,recv() 先是大小,然后是recv() 需要的数据。

例如(为了简洁省略错误处理,不要忽略错误处理!):

FILE *script;
int j, k, read;
uint32_t size, size2;
char codigo[1024];
if (argc > 1)
{
    for (j = 1; j < argc; j++)
    {
        script = fopen(argv[j], "rb");
        if (script == NULL)
        {
            perror(argv[j]);
            continue;
        }

        fseek(script, 0, SEEK_END);
        size = ftell(script); 
        fseek(script, 0, SEEK_SET);

        struct addrinfo hints;
        struct addrinfo *serverInfo, *server;

        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_UNSPEC; 
        hints.ai_socktype = SOCK_STREAM;

        getaddrinfo(ip, puerto, &hints, &serverInfo);

        int serverSocket = -1;

        for(server = serverInfo; server != NULL; server = server->ai_next)
        {
            serverSocket = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
            if (serverSocket != -1)
            {
                if (connect(serverSocket, server->ai_addr, server->ai_addrlen) == 0)
                    break;
                close(serverSocket);
                serverSocket = -1;
            }
        }

        freeaddrinfo(serverInfo);  

        if (serverSocket != -1)
        {
            printf("Conectado al servidor\n");

            size2 = htonl(size);
            send(serverSocket, (char*)&size2, sizeof(size2), 0);

            for(k = 0; k < size;)
            {
                read = fread(codigo, sizeof(char), 1024, script);
                if (read < 1) break;
                send(serverSocket, codigo, read, 0);
                k += read;
            }

            close(serverSocket);
        }

        fclose(script);
    }
}

FILE *script;
int j, read;
uint32_t size;
char codigo[1024];

int clientSocket = accept(...);
script = fopen(..., "wb");

recv(clientSocket, (char*)&size, sizeof(size), 0);
size = ntohl(size);

for(j = 0; j < size;)
{
    read = recv(clientSocket, codigo, 1024, 0);
    if (read < 1) break;
    fwrite(codigo, sizeof(char), read, script);
    j += read;
}

fclose(script);
close(clientSocket);

【讨论】:

  • 好的,我实现了这个。发送大小(很长),然后我认为它发送数据但不打印。
  • htonl() 将数字从 主机字节顺序 转换为 网络字节顺序,然后 ntohl() 将其转换回来。您应该始终按网络字节顺序发送整数,以便在不同机器和平台之间保持兼容性。是的,您可以使用固定的 1024 字节数组。看看代码实际上在做什么。它以 1024 字节块的形式读取文件,发送它实际读取的任何字节,直到到达文件末尾。文件大小实际上是可变长度。在发送之前,您不必(也不应该)将整个文件读入内存。接收端也一样。
猜你喜欢
  • 2017-03-14
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 2011-02-24
  • 1970-01-01
相关资源
最近更新 更多