send multiple pics from folder via socket

Pages: 12
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
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.
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.
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()
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
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
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.
> 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)

@ 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
server_5.cpp:138:1: error: ‘else’ without a previous ‘if’

you did nothing of what was asked

also missing client side code
> 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