image won't open

Pages: 12
A misunderstanding must be happening, since I haven't posted a single line that wouldn't be connected
to the problems I'm facing.

here is the receiver (in python)

1
2
3
4
5
6
7
data_1 = socket.recv(4)
data_size = int.from_bytes(data, byteorder='big', signed=False)

data_2=socket.recv(data_size)

file=open('image.jpeg','wb')
file.write(data_2)


the socket is TCP, if that's what you are asking, and both server and client are well connected.

The lines you wrote are very easy to understand, but I am not sure how do they relate to send bytes via socket.
Last edited on
As ne555 suggested, I wouldn't start with a full image. Start with small words and then try paragraphs worth of plain text, to make sure all that is being received properly.

This is just a guess, but doesn't Python require file.close() to make sure the data is flushed?

as I mentioned, everything is working fine when it comes to communication between server and client.
I sent messages from one side to another, and they are all received and displayed.
The only problems I have left are the ones I mentioned.
I now repeat:
a full image works, if I don't send the size before the image, or sending the size as an integer works too
but then the image generated is faulty.
no worries,
however, with this being said, I now wanted to ask how should I send multiple images from a folder via socket ?
As explained, if I send one without sending the size beforehand, I succeed.
But I am not sure how to send a bunch of them from a folder.
Any hints ?
Basically, work out what's going wrong such that you can only send one thing, and fix that. Then you can send as many as you like.

This might require you having to send some test data. For example, what happens if you send the number 1, and then the number 2? Does the second number arrive? What value do you read? Can you identify from that simple value what is going wrong?

If you open the jpeg image received with a hex editor, what's in it? Can you see the jpeg header information? Does looking at it give you any clue what's going wrong?
Last edited on
@ repeater
As I said before, sending one image is not a problem, but when it comes to send multiple images I get stuck, because I am not sure how to change the line in question.
This is the code that successfully sends one image.
Is there a way to change perhaps the first line in order to send many images ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char file_name[] ={"/home//Desktop/pics/pic_1.jpeg"};
ifstream stream(file_name, std::ios::in | std::ios::binary);
vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
cout << "Size: " << imageDataVec.size() << " bytes";

size_t sent{};
while (sent < imageDataVec.size()) {
    int nbytes = send(new_socket, &imageDataVec[sent], imageDataVec.size() - sent, 0);
    if (nbytes <= 0) {
        std::clog << "error: while sending image\n";
        break;
    }
    sent += nbytes;
    cout<<nbytes<<"================"<<endl;

}
As I said before, sending one image is not a problem, but when it comes to send multiple images I get stuck, because I am not sure how to change the line in question.


You said that the second image, the second thing you send, DOES arrive, yes? But there is something wrong with it. What is wrong with it? Is it the right size? If it is the right size, what is wrong with the data?


Try sending two images. Does THIS work? Does THIS send two images? If not, why? What is wrong with the second image?
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
char file_name[] ={"/home//Desktop/pics/pic_1.jpeg"};
ifstream stream(file_name, std::ios::in | std::ios::binary);
vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
cout << "Size: " << imageDataVec.size() << " bytes";

size_t sent{};
while (sent < imageDataVec.size()) {
    int nbytes = send(new_socket, &imageDataVec[sent], imageDataVec.size() - sent, 0);
    if (nbytes <= 0) {
        std::clog << "error: while sending image\n";
        break;
    }
    sent += nbytes;
    cout<<nbytes<<"================"<<endl;

}

char file_name2[] ={"/home//Desktop/pics/pic_2.jpeg"}; // DIFFERENT FILE
ifstream stream(file_name2, std::ios::in | std::ios::binary);
vector<char> imageDataVec2((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
cout << "Size: " << imageDataVec2.size() << " bytes";

size_t sent2{};
while (sent2 < imageDataVec2.size()) {
    int nbytes = send(new_socket, &imageDataVec2[sent2], imageDataVec2.size() - sent2, 0);
    if (nbytes <= 0) {
        std::clog << "error: while sending image\n";
        break;
    }
    sent2 += nbytes;
    cout<<nbytes<<"================"<<endl;

}
Last edited on
well, what I mean is: instead of repeating the code, would it be possible to iterate the first line to send multiple pictures?
and the problem that I have, doesn't show after sending more than one image, as I haven't managed yet to do so, but once I include these lines between line 21 and line 23

1
2
long converted_number = htonl(imageDataVec.size());
send(new_socket, &converted_number, sizeof(converted_number), 0);


the picture that the client generates is not a jpeg file but something corrupt, showing the problem that I listed when I first open this thread.
Is it clear now? Or else, ask.
Last edited on
You can repeat code as many times as you like. The common way to do this is to make it a function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void sendFile(char* file_name)
{
  ifstream stream(file_name, std::ios::in | std::ios::binary);
  vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
  cout << "Size: " << imageDataVec.size() << " bytes";

  size_t sent{};
  while (sent < imageDataVec.size()) {
      int nbytes = send(new_socket, &imageDataVec[sent], imageDataVec.size() - sent, 0);
      if (nbytes <= 0) {
          std::clog << "error: while sending image\n";
          break;
      }
      sent += nbytes;
      cout<<nbytes<<"================"<<endl;
  }
}


Then call it many times:

1
2
3
4
5
sendFile("/home//Desktop/pics/pic_1.jpeg");
sendFile("/home//Desktop/pics/pic_2.jpeg");
sendFile("/home//Desktop/pics/pic_3.jpeg");
sendFile("/home//Desktop/pics/pic_4.jpeg");
sendFile("/home//Desktop/pics/pic_5.jpeg");



the picture that the client generates is not a jpeg file but something corrupt

But WHAT is wrong with the file? Is it the right size? Is all the data zero? Is the data backwards? WHAT is wrong with the data?

Data is just numbers. What is wrong with the numbers?

If it's difficult to work out what is wrong with all the numbers, what if you just send ONE number. If you just send ONE number, what goes wrong? What number do you receive at the other end.

Yes, yes, I know what you're about to say. You're about to say that when you send a number, it's fine. So send TWO numbers, and if the second number goes wrong, what went wrong with that number?
Last edited on
You can repeat code as many times as you like. The common way to do this is to make it a function:


The thing is that I will eventually have to implement this code to a network camera which will send images one after the other to the client, therefore I would need only one "send" command which will send this stream "live".
Since I don't have access to that camera at home, I am trying with random pictures from a folder for now.
At this point, if you have any suggestion on how should I work at home while lacking such a camera, I will gladly consider your suggestion, if you believe you have a better idea than using pics in a folder.


But WHAT is wrong with the file? Is it the right size? Is all the data zero? Is the data backwards? WHAT is wrong with the data?

Data is just numbers. What is wrong with the numbers?


I am not sure how to explain it more clearly. The server sends the file, and once the client receives it, saves it on the desktop. I click on it, and this is what appears: https://stackoverflow.com/questions/46130953/error-interpreting-jpg-file-not-a-jpg-file-starts-with-0xff-0x28
Two things you could do to better understand the problem:

1. use a hex editor to view the contents of the jpg file. You can view the contents of ANY file to see the individual bytes it is made of.

2. Send a text file instead of an image file. Then look at the text file to see what it contains.

@ chervil

the content of the file is clearly shown in this link:
https://stackoverflow.com/questions/46130953/error-interpreting-jpg-file-not-a-jpg-file-starts-with-0xff-0x28

yet, is still not clear what should I do once I know it.

My code already sends/receives messages successfully,
but again, once I know the content, which I already know, since messages are strings,
what should I do with it?
How is everything you are suggesting related to sending multiple pictures?

All I want to know is how to change my code to make sure that instead of only one image from the same folder, all of the images from the same folder are sent.
All I want to know is how to change my code to make sure that instead of only one image from the same folder, all of the images from the same folder are sent.


You've been told that already. You get a list of the files, and then you call your sending function on each file.

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
void sendFile(char* file_name)
{
  ifstream stream(file_name, std::ios::in | std::ios::binary);
  vector<char> imageDataVec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
  cout << "Size: " << imageDataVec.size() << " bytes";

  size_t sent{};
  while (sent < imageDataVec.size()) {
      int nbytes = send(new_socket, &imageDataVec[sent], imageDataVec.size() - sent, 0);
      if (nbytes <= 0) {
          std::clog << "error: while sending image\n";
          break;
      }
      sent += nbytes;
      cout<<nbytes<<"================"<<endl;
  }
}


// GET LIST OF FILES

for ( auto filename : list_of_files)
{
  sendFile(file);
}


@ chervil

the content of the file is clearly shown in this link:
https://stackoverflow.com/questions/46130953/error-interpreting-jpg-file-not-a-jpg-file-starts-with-0xff-0x28

I see the first two bytes there. I was looking for about the first fifty or hundred bytes from the file.


yet, is still not clear what should I do once I know it.


Once you have that additional information, you could post it here.

The aim is to obtain information about exactly what is happening. Then possible remedies can be found. At this stage it still doesn't seem that there is a clear diagnosis of the cause.

That's why I suggested sending a text file. It tends to be easier to spot changes (extra characters or missing characters or changed characters, for example) in a text file.
1
2
data_1 = socket.recv(4)
data_size = int.from_bytes(data /*this should be data_1*/, byteorder='big', signed=False)
You've been told that already.
ROFL, poor ol Repeater, started off 4 or 5 days ago on this with exuberant promise of knowing what to do. Now just a big hole and a witless heap of anger.
@ repeater,

I am sorry that you had to repeat yourself.
I should have perhaps been more clear.
I acknowledged the suggestion of writing the function and repeat it for every file, but what I meant was
a way to send all the picture with only one "send" command, instead of a command for each file.
Maybe your way works too, but I am only afraid that on the client side, I would have to write a "recv" command for every file I receive, and I am not supposed to do that.
Do you have a better Idea of what I mean now? Or still confusing ?
Day 6 and the xy problem still not answered, instead evolving slowly into an xyz.

Probably your source file is corrupt.

But who cares? The interaction between OP and repeater fumbling around in the dark is sort of entertaining.

What lies ahead in the next episode of "Days of Our Jpegs"
1
2
long converted_number = htonl(imageDataVec.size());
send(new_socket, &converted_number, sizeof(converted_number), 0);

Do you know what sizeof(long) is on your machine?
Look at Repeater's code in the very next post - the one where the return result of send is checked and retried to make sure the whole data is sent.

> here is the receiver (in python)
1
2
3
4
5
6
7
data_1 = socket.recv(4)
data_size = int.from_bytes(data, byteorder='big', signed=False)

data_2=socket.recv(data_size)

file=open('image.jpeg','wb')
file.write(data_2)

Right, and how much debugging did you do?
You're fumbling around in the dark wondering what could be wrong, yet do nothing to try and figure it out.

1
2
3
4
5
6
7
8
9
data_1 = socket.recv(4)
data_size = int.from_bytes(data, byteorder='big', signed=False)
print("received size={}".format(data_size))

data_2=socket.recv(data_size)
print("received data len={}".format(len(data_2)))

file=open('image.jpeg','wb')
file.write(data_2)


And since you used htonl on the send, then use the reverse on the receiver.
https://docs.python.org/3.5/library/socket.html?highlight=ntoh#socket.ntohl

I doubt your images fit in a single 4K buffer.
https://docs.python.org/3.5/library/socket.html?highlight=recv#socket.socket.recv

For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096.

The same reason you have a loop on the send() also applies to recv() as well.

Last edited on
Topic archived. No new replies allowed.
Pages: 12