在套接字客户端服务器中发送多个文件

巴卡洛洛

我想在单个客户端服务器连接上发送多个文件。服务器应该接受来自客户端的连接,然后循环遍历文件夹并将其中的每个文件发送到客户端。有什么好的方法可以做到这一点,以便客户端在收到每个文件后可以保存它们,然后正确读取下一个文件。

我有以下服务器代码,它只发送 1 个文件并关闭。

/*
    Server side C/C++ program to demonstrate Socket programming

    compile:
        gcc serverFile.c -o serverFile
    run:
        ./serverFile

    from http://www.geeksforgeeks.org/socket-programming-cc/ 
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>

#define PORT 8080

int main(int argc, char const *argv[])
{


    char *file_path = "image.jpg";
    int input_file;

    input_file = open(file_path, O_RDONLY);
    if (input_file == -1) {
        exit(EXIT_FAILURE);
    }


    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";

    // Creating socket file descriptor. AF_INET is IPv4, SOCK_STREAM is tcp.
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    //Set socket option (optional?).  SOL_SOCKET is socket level argument.  
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                                                  &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address, 
                                 sizeof(address))<0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    // If you want to read multiple server connections.
    //int x;
    //for (x = 0; x < 3; x++){
    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, 
                       (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );

    /*********************** read file and send it over socket ****************************/


    //unsigned char buffer[1000];
    while (1) {
            // Read data into buffer.  We may not have enough to fill up buffer, so we
            // store how many bytes were actually read in bytes_read.
            int bytes_read = read(input_file, buffer, sizeof(buffer));
            if (bytes_read == 0) // We're done reading from the file
                break;

            if (bytes_read < 0) {
                // handle errors
                printf("read error!\n");
            }

            // You need a loop for the write, because not all of the data may be written
            // in one call; write will return how many bytes were written. p keeps
            // track of where in the buffer we are, while we decrement bytes_read
            // to keep track of how many bytes are left to write.
            void *p = buffer;
            while (bytes_read > 0) {
                int bytes_written = write(new_socket, p, bytes_read);
                if (bytes_written <= 0) {
                    // handle errors
                }
                bytes_read -= bytes_written;
                p += bytes_written;
            }
    }

    /***************************************************************************************/

    //send(new_socket , hello , strlen(hello) , 0 );
    //printf("Hello message sent\n");

    close(new_socket);
    close(server_fd);
    //} 
    return 0;
}
巴卡洛洛

这就是我想出来的,如果有人有任何建设性的批评,我很乐意听到。与我写的 python 客户端一起工作得很好,可以读取 10 字节(文件大小)、50 字节(文件名)和文件大小字节(文件数据)。

/*
    Server side C/C++ program to demonstrate Socket programming

    compile:
        gcc serverMultipleFileV2.c -o serverMultipleFileV2
    run:
        ./serverMultipleFileV2

    from http://www.geeksforgeeks.org/socket-programming-cc/ 
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <stddef.h>
#include <dirent.h>

#define PORT 8080

int main(int argc, char const* argv[])
{

    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = { 0 };
    char* hello = "Hello from server";

    // Creating socket file descriptor. AF_INET is IPv4, SOCK_STREAM is tcp.
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    //Set socket option (optional?).  SOL_SOCKET is socket level argument.
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
            &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr*)&address,
            sizeof(address))
        < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr*)&address,
             (socklen_t*)&addrlen))
        < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    valread = read(new_socket, buffer, 1024);
    printf("%s\n", buffer);

    /*********************** read file and send it over socket *************************/

    DIR* dir;
    struct dirent* ent;

    if ((dir = opendir("images/")) == NULL) {
        printf("Couldn't open directory");
        exit(EXIT_FAILURE);
    }

    // loop through folder and read /send all files.
    while ((ent = readdir(dir)) != NULL) {

        if (!strcmp(ent->d_name, ".")) {
            continue;
        }

        if (!strcmp(ent->d_name, "..")) {
            continue;
        }

        // get the filename e.g. [CAM1]image6-2017-12-13-21-32-24.jpg
        char file_name[50];
        strncpy(file_name, ent->d_name, 49);
        file_name[49] = '\0';

        // get the filepath e.g. images/[CAM1]image6-2017-12-13-21-32-24.jpg
        char pathname[80];
        char * filename = "images/";
        strcpy(pathname, filename);
        strcat(pathname, file_name);

        printf("FILENAME: %s\n", file_name);
        printf("PATHNAME: %s\n", pathname);

        // open file for read
        int input_file;
        input_file = open(pathname, O_RDONLY);
        if (input_file == -1) {
            printf("Couldn't read file!\n");
            exit(EXIT_FAILURE);
        }

        /*********Send filesize over socket*****/
        // get filesize
        struct stat st;
        stat(pathname, &st);
        long file_size = (long)st.st_size;
        char fileSizeString[10];
        // convert file_size to string
        const int n = snprintf(NULL, 0, "%lu", file_size);
        assert(n > 0);
        int c = snprintf(fileSizeString, n + 1, "%lu", file_size);
        assert(fileSizeString[n] == '\0');
        assert(c == n);
        printf("file size:%s\n", fileSizeString);
        int bytes_written = write(new_socket, fileSizeString, sizeof(fileSizeString));

        /*********Send filename over socket*****/
        bytes_written = write(new_socket, file_name, sizeof(file_name));

        /*********Send filedata over socket*****/
        while (1) {
            // Read data into buffer.  We may not have enough to fill up buffer, so we
            // store how many bytes were actually read in bytes_read.
            int bytes_read = read(input_file, buffer, sizeof(buffer));
            if (bytes_read == 0) // We're done reading from the file
                break;

            if (bytes_read < 0) {
                // handle errors
                printf("read error!\n");
                exit(EXIT_FAILURE);
            }

            // You need a loop for the write, because not all of the data may be written
            // in one call; write will return how many bytes were written. p keeps
            // track of where in the buffer we are, while we decrement bytes_read
            // to keep track of how many bytes are left to write.
            void* p = buffer;
            while (bytes_read > 0) {
                int bytes_written = write(new_socket, p, bytes_read);
                if (bytes_written <= 0) {
                    // handle errors
                }
                bytes_read -= bytes_written;
                p += bytes_written;
            }

        } 

    }
    closedir(dir);
    close(new_socket); //close connection with specific client
    close(server_fd); // close connection to stop listening

    return 0;
}

蟒蛇客户端

# Read header size and multiple file data over tcp socket
#!/usr/bin/env python

import socket
import sys
import string

TCP_IP = '192.168.0.102'
TCP_PORT = 8080

MESSAGE = "Hello, bakalolo speaking"

#f = open('torecv.jpg','wb')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)

while(True):

    print "*************************************************"

    # ----------Read file size (10 bytes) from socket-----
    fileSizeRecievedCounter = 0 #store number of file size bytes read so far
    fileSize = "" # store file size data as string when read
    l = s.recv(10)
    # if no more data left, all images should be read from server.
    if len(l) == 0:
        break 
    fileSizeRecievedCounter += len(l) #incriment bytes read counter
    fileSize += l #concat read data to filename
    # Keep reading until we have 10 bytes just in case
    while(fileSizeRecievedCounter < 10):
        l = s.recv(10 - fileSizeRecievedCounter)
        fileSizeRecievedCounter += len(l)
        fileSize += l

    print "file sizeb4convert:", repr(l)
    l = l.split('\0', 1)[0]
    #l = filter(lambda x: x in string.printable, l) #remove byte values from string
    fileSize = int(l)
    print "file size:", repr(fileSize)

    # ----------Read file name (50 bytes) from socket-----
    fileNameRecievedCounter = 0 #store number of file name bytes read so far
    fileName = ""
    # read file name
    l = s.recv(50)
    fileNameRecievedCounter += len(l) #incriment bytes read counter
    fileName += l #concat read data to filename
    while(fileNameRecievedCounter < 50):
        l = s.recv(50 - fileNameRecievedCounter)
        fileNameRecievedCounter += len(l)
        fileName += l

    print "file nameb4convert:", repr(fileName)
    fileName = fileName.split('\0', 1)[0]
    #fileName = filter(lambda x: x in string.printable, l)
    print "file name:", repr(fileName)


    f = open(fileName,'wb')
    # read file data
    fileSizeRecieved = 0 #store number of bytes read so far
    l = s.recv(1024)
    f.write(l)
    fileSizeRecieved += len(l) #add bytes read to counter
    while (l):

        if fileSizeRecieved == fileSize:
            break

        bytesLeft = fileSize - fileSizeRecieved
        if bytesLeft < 1024: #if less than 1024 bytes left, read how much is left
            l = s.recv(bytesLeft)
            f.write(l)
            fileSizeRecieved += len(l)
        else:
            l = s.recv(1024)
            f.write(l)
            #print "Receiving...", len(l)
            fileSizeRecieved += len(l)

    print "Done receiving! Total:", fileSizeRecieved

f.close()
s.close()

#print "received data:", l

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Spring Integration和TCP服务器套接字-如何向客户端发送消息?

来自分类Dev

Python套接字服务器/客户端编程

来自分类Dev

音频数据的TCP套接字通信-多个服务器到多个客户端

来自分类Dev

C客户端/服务器套接字错误

来自分类Dev

套接字io,节点js,从服务器向客户端发送图像/文件的简单示例

来自分类Dev

通过python中的TCP套接字在客户端-服务器之间发送文件?

来自分类Dev

使用C中的套接字将文件从客户端发送到服务器

来自分类Dev

使用套接字从服务器向客户端发送静态文件

来自分类Dev

使用套接字将值从服务器发送到客户端

来自分类Dev

如何将数据从Web套接字服务器发送到客户端?

来自分类Dev

服务器/客户端套接字连接

来自分类Dev

客户端套接字未完全收到服务器端套接字发送的内容

来自分类Dev

套接字服务器无法接收客户端发送的消息

来自分类Dev

套接字编程-简单的客户端/服务器

来自分类Dev

TCP套接字,发送文件,客户端服务器,服务器不保存整个文件,C语言

来自分类Dev

客户端js上的套接字服务器?

来自分类Dev

使用python套接字将Txt文件从客户端发送到服务器

来自分类Dev

通过ActionScript服务器和Java客户端之间的套接字发送对象

来自分类Dev

使用套接字C#客户端/服务器发送文件

来自分类Dev

Java套接字-将数据从服务器发送到客户端

来自分类Dev

通过python中的TCP套接字在客户端-服务器之间发送文件?

来自分类Dev

服务器无法通过C中的套接字向客户端发送消息

来自分类Dev

Java多线程套接字客户端/服务器:发送和接收Enummap对象

来自分类Dev

Java套接字-将数据从客户端发送到服务器

来自分类Dev

套接字发送客户端服务器文件

来自分类Dev

Java客户端/服务器套接字问题

来自分类Dev

从Node JS Socket客户端向MINA套接字服务器发送消息

来自分类Dev

C posix套接字,无法从客户端向服务器发送数据

来自分类Dev

套接字服务器同时响应来自客户端套接字的多个请求

Related 相关文章

  1. 1

    Spring Integration和TCP服务器套接字-如何向客户端发送消息?

  2. 2

    Python套接字服务器/客户端编程

  3. 3

    音频数据的TCP套接字通信-多个服务器到多个客户端

  4. 4

    C客户端/服务器套接字错误

  5. 5

    套接字io,节点js,从服务器向客户端发送图像/文件的简单示例

  6. 6

    通过python中的TCP套接字在客户端-服务器之间发送文件?

  7. 7

    使用C中的套接字将文件从客户端发送到服务器

  8. 8

    使用套接字从服务器向客户端发送静态文件

  9. 9

    使用套接字将值从服务器发送到客户端

  10. 10

    如何将数据从Web套接字服务器发送到客户端?

  11. 11

    服务器/客户端套接字连接

  12. 12

    客户端套接字未完全收到服务器端套接字发送的内容

  13. 13

    套接字服务器无法接收客户端发送的消息

  14. 14

    套接字编程-简单的客户端/服务器

  15. 15

    TCP套接字,发送文件,客户端服务器,服务器不保存整个文件,C语言

  16. 16

    客户端js上的套接字服务器?

  17. 17

    使用python套接字将Txt文件从客户端发送到服务器

  18. 18

    通过ActionScript服务器和Java客户端之间的套接字发送对象

  19. 19

    使用套接字C#客户端/服务器发送文件

  20. 20

    Java套接字-将数据从服务器发送到客户端

  21. 21

    通过python中的TCP套接字在客户端-服务器之间发送文件?

  22. 22

    服务器无法通过C中的套接字向客户端发送消息

  23. 23

    Java多线程套接字客户端/服务器:发送和接收Enummap对象

  24. 24

    Java套接字-将数据从客户端发送到服务器

  25. 25

    套接字发送客户端服务器文件

  26. 26

    Java客户端/服务器套接字问题

  27. 27

    从Node JS Socket客户端向MINA套接字服务器发送消息

  28. 28

    C posix套接字,无法从客户端向服务器发送数据

  29. 29

    套接字服务器同时响应来自客户端套接字的多个请求

热门标签

归档