[try Beta version]
Not logged in

 
send multiple pics from folder via socket

Pages: 12
Feb 21, 2020 at 8:48pm
try simple things and make sure that works first


I have tried to use this same exact code with one txt file I just created and put in a folder (yes, just one file in a folder). The txt file only contains the word 'hey', just to make it simple.
The file was transferred to the client and once I opened it, it looked very strange , and this message showed:

There was a problem opening the file /home/Desktop/downloaded_pics/new_text.txt.

and the actual bytes showed too:

\85\89\8E\F8.

but no actual file.

What exactly is happening?
Does anyone know?

What shows once I click on the generated document by the client, looks exactly the same as this:
https://cs50.stackexchange.com/questions/5905/my-bmp-files-are-not-opening-up-but-rather-showing-the-error-unable-to-open-the/5907
Last edited on Feb 21, 2020 at 9:07pm
Feb 22, 2020 at 6:42am
In case it isn't obvious by now, we simply don't trust you to write a program to do anything remotely close to what you intended.

Saying you "did X and got Y" tells us nothing about the myriad possible ways you could have (and continue) to screw up.

So post your 'simple text sender' and 'simple text receiver' and let us judge where the problems are.
Feb 22, 2020 at 8:12am
You will always have issues with your app because the protocol (the message exchange between the client and server) is ambiguous. The client and server cannot know when it's right to send anything. That should be the first thing you define.

For example, when the client starts up, it reads a message from the server, then sends two. But those two will be received as a single message by the server. There are no delimiters or lengths sent, so the client or server cannot know when the message is complete.
Feb 22, 2020 at 10:27am
post your 'simple text sender' and 'simple text receiver' and let us judge where the problems are.


I didn't post it because the code is the same as before, the only difference is that the folder that I am using, contains only one txt file, but anyway, here you go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
const char *dir = "/home/Desktop/text_files";

    if (chdir(dir) == -1) {
        perror(dir);
        return 1;
    }

    DIR *dirp = opendir(".");

    for (struct dirent *dent; (dent = readdir(dirp)) != NULL; )
    {
        const char *nm = dent->d_name;

        if (strcmp(nm, ".") == 0 || strcmp(nm, "..") == 0)
            continue;

        struct stat file_stats;
        if (stat(nm, &file_stats) == -1)
            perror(nm);

       /*else
           {//printf("%9u: %s\n", (unsigned)file_stats.st_size, nm);
            
               long converted_number = htonl((unsigned)file_stats.st_size);
            int size_chunks=0;
            size_chunks=send(new_socket, &converted_number, sizeof(converted_number), 0); //send image  sizes 
            cout<<size_chunks<<"=====1=1=1=1========"<<"bytes"<<endl;
            //break;
            }*/




ifstream stream(nm, std::ios::in | std::ios::binary);  
if(stream.is_open())                                     //open folder
    {


        vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
        cout << "Size=of=image=== " << imageDataVec.size() << " bytes";
        long conv_num= htonl(imageDataVec.size());
        //send(new_socket, &converted_number, sizeof(converted_number), 0);
        //send(new_socket, &imageDataVec, imageDataVec.size() , 0);

//size_t sent{};
int nbytes=0;  

    while (1) 
        {
         
        //send(new_socket, &conv_num, sizeof(conv_num), 0);
         nbytes = send(new_socket, &imageDataVec, imageDataVec.size(), 0);
    //continue;
        if (nbytes <= 0) {
            std::clog << "error: while sending image\n";
            break;
    }
        else
    {
        //sent += nbytes;
        cout<<nbytes<<"=====1=1=1=1========"<<"bytes"<<endl;
    }
                           break;
     
        }
    //fclose(fin);

}
else
{cout<<"can't open folder"<<endl;}


}


closedir(dirp);



    close(s);
    close(new_socket);
    return 0; 
}


1
2
3
4
5
6
7
8
f = codecs.open('/home/Desktop/downloaded_pics/new_text.txt', 'wb')

data = s.recv(3)
print(data)  # it prints  b'\x00\xe5\x13', remember, the txt file only contains the word 'hey'
f.write(data)


f.close()
Feb 22, 2020 at 12:57pm
nbytes = send(new_socket, &imageDataVec, imageDataVec.size(), 0);
that's wrong

nbytes = send(new_socket, &imageDataVec[0], imageDataVec.size(), 0);or use .data()


also
1
2
3
char c
while(std::cin >> c)
   send(new_socket, &c, sizeof(c), 0);

no vector involved, no reading from a file, no directory traversal, less chances for a screw-up


> A bloated and poorly indented main is ripe for lots of unforced errors
> because you can't keep everything organised.
>> this is the way I do my work, and as a programmer, I'm sure you know that we
>> all have our ways of writing.
bad indented code is plain obfuscation
don't try to justify it, just learn to indent.
Last edited on Feb 22, 2020 at 1:04pm
Feb 22, 2020 at 1:56pm
Thank you ne555.
The [0] added to nbytes made the difference and the document generated by the client had no problem.
However, going back to the images , I have made that change, but I still have the same problem as before.
The images generated are usually no more than 1 or 2 (the folder contains 5 images), and once they are created, they show problems of the same nature as the one related to txt sending (see link above).
Moreover, it looks like that the client is only receiving the first two sizes, properly, the rest are just strangely large numbers.
I am here posting both codes again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
const char *dirr = "/home/Desktop/pics";

    if (chdir(dirr) == -1) {
        perror(dirr);
        return 1;
    }

    DIR *dirpp = opendir(".");

    for (struct dirent *dent; (dent = readdir(dirpp)) != NULL; )
    {
        const char *nm = dent->d_name;

        if (strcmp(nm, ".") == 0 || strcmp(nm, "..") == 0)
            continue;

        struct stat file_stats;
        if (stat(nm, &file_stats) == -1)
            perror(nm);



ifstream stream(nm, std::ios::in | std::ios::binary);

if(stream.is_open())
    {


vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
cout << "Size=of=image=== " << imageDataVec.size() << " bytes";
long conv_num= htonl(imageDataVec.size());
//send(new_socket, &converted_number, sizeof(converted_number), 0);
//send(new_socket, &imageDataVec, imageDataVec.size() , 0);

size_t sent{};
//int nbytes=0;  

while (1) 
    {
     
    //send(new_socket, &conv_num, sizeof(conv_num), 0);
     int nbytes = send(new_socket, &imageDataVec[0], imageDataVec.size(), 0);
//continue;
    if (nbytes <= 0) {
        std::clog << "error: while sending image\n";
        break;
}
    else
{
    
sent += nbytes;
   ///nbytes;
    cout<<nbytes<<"=====1=1=1=1========"<<"bytes"<<endl;}
                       break;
 
    }
//fclose(fin);
}
else
{cout<<"can't open folder"<<endl;}

}


closedir(dirp);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
list_of_bytes=[]
f = open('/home/Desktop/downloaded_pics/new_pic.jpeg', 'wb')
#for i in range(10):
while(1):
    data = s.recv(4)
    print(data)
    #if b'\x00\x00\x00\x00' in data:
     #   continue
    #print(data)
    data_bytes_amount = int.from_bytes(data, byteorder='big', signed=False)
    list_of_bytes.append(data_bytes_amount)
    print("received size={}".format(data_bytes_amount))
    print(data_bytes_amount)
    
    pictures=s.recv(data_bytes_amount)
    f.write(pictures)
    if not data:
        break
Feb 22, 2020 at 3:04pm
0. write a pseudocode
1. indent your code
2. post a complete program. Given the size, and that your changes are kinda small, I'll suggest to upload your project to github or similar and tell us when you update it.
3. comment your code

see you then.
Feb 22, 2020 at 3:30pm
> int nbytes = send(new_socket, &imageDataVec[0], imageDataVec.size(), 0);
Go back and read all the previous posts that tell you that send() will NOT send an arbitrarily large buffer in a single call.

If you keep assuming this, you're always doomed to fail.

Sure it works for a handful of characters out of a text file.
But you're writing megabytes at a time now.

In http://www.cplusplus.com/forum/general/268109/
> ssize_t sendBytes(int sockfd, const void *buf, size_t len)

Feb 23, 2020 at 8:58pm
@ salem
Go back and read all the previous posts that tell you that send() will NOT send an arbitrarily large buffer in a single call.


this confuses me. The 'send' command is inside a loop, so is not sending everything in a single call.
What do you mean by 'single call' then?

In short, in order to make sure I don't run in this mistake, do I need to change a lot in my code, or is sufficient to make small changes?

Just in case is helpful for you to know, I have tried to leave only one image in the folder, and the problems that I am running into are the same. However, I would like to point out that on the receiver side, I am receiving a first chunk byte which correspond to the same exact size of the image I left in the folder, and another chunk which is much bigger and I have no Idea where does it come from, since the server is only printing the first chunk.

@ne555
https://github.com/denbja9/dnebja9
Last edited on Feb 23, 2020 at 9:16pm
Feb 24, 2020 at 1:40pm
server_5.cpp:138:1: error: ‘else’ without a previous ‘if’

you did nothing of what was asked

also missing client side code
Feb 24, 2020 at 6:00pm
> this confuses me. The 'send' command is inside a loop, so is not sending everything in a single call.
You're mis-understanding 'everything'

send() doesn't give a monkey's about what you're sending.

This is what I mean by a single call to send.
 
int r = send(sock,"hello",5,0);

If you assume that r will always be 5, then you're doomed to fail at some point.
This is simply not what send() promises to do.
It's YOUR RESPONSIBILITY to deal with the cases when r is NOT the number of bytes you asked to be sent.

You can call send() as many times as you like, but if you keep ignoring the return result, there's no hope for you.

I showed you this about a week ago.
Topic archived. No new replies allowed.
Pages: 12