Master Reader/Slave Sender with Distance Sensor
Your code has some flaws, that I will address here:


The main problem, that you see here, is that you only let the slave write data into the buffer, when it is receiving data. But you never send data to it. So there is never anything in the buffer.

In the slave code you have

void receiveEvent(int howMany)
{
  while(1 &lt; Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);    
  Wire.write(count);
  Wire.write(contor);
}


Besides the unbalanced parentheses (which let's me think, that this might not be the actual code, that you are running currently), you are writing to the buffer only inside the receiveEvent(). That only get's called, when the master does a Master-Write transmission (via Wire.beginTransmission() and Wire.endTransmission()). In the master code you are only using Wire.requestFrom(). If you want to send back data on a request, you need to use the onRequest callback of the Wire library. You need to set the appropriate callback function:

Wire.onRequest(onRequestEvent);


And then write data inside that callback function:

void onRequestEvent(){
    Wire.write(...)
}


I will explain how to write the values correctly in a different point below.
In the receiveEvent() function you want to loop through all received bytes but the last. But you are not doing anything with the data. You aren't even reading it. As your code currently stands, this line does not make any sense.
In your master code you are requesting data from the slave with the address 2. Your slave code initiates the Wire library with the address 4. From that point there should never be a successful I2C transmission, unless you have another slave on the bus with the address 2 (another point, where I suspect, that these codes are not exactly the ones used for the test).
In the master code you are using

while(Wire.available())


because the slave might have send less data, than requested. You are testing, that the number of available bytes is not zero. But then you are reading 3 bytes without checking again, which means, when you received 2 byte, you still would try to read 3 bytes, which cannot give good results.

The condition should be Wire.available() &gt;= 3, to check, if at least 3 bytes are in the buffer, because you are reading 3 bytes from it. But also the loop does not make much sense to me. As you have a binary protocol here, how would you treat additional data (meaning excess data, send after the first valid data frame)? You want to receive 3 values per transmission and you are reading 3 values in one iteration of the loop. If there where more data in the buffer, you would be reading the next 3 bytes, throwing away the first 3 bytes. I don't think, that is what you want.

Instead use the return value of Wire.requestFrom(), which is the number of received bytes. Use it to distinguish valid transmissions, from those, which are too short:

uint8_t n = Wire.requestFrom(4, 3);
if(n &gt;= 3){ // at least 3 bytes where received
    uint8_t value1 = Wire.read();
    uint8_t value2 = Wire.read();
    uint8_t value3 = Wire.read();
}


Any transmission, that is too small, will get ignored. Excess data in too long messages will also be ignored. Note, that I used uint8_t, which is an unsigned integer with 8 bits (1 byte) here for simplicity of that points logic. More about your data types and their implications on your code below.
For the to send datatypes on the slave you have int and long. int is a signed integer with 16 bits, long is a signed long integer with 32 bits. (I suspect you don't need a long for the distance, as ultrasonic sensors mostly reach only 3m, but that is up to you). In contrast the argument of Wire.write() is an uint8_t, which has only 8 bits. That call is used to put exactly 1 byte into the buffer, not more. When you are using

Wire.write(Distanceincm);


you are putting the least significant byte of Distanceincm into the buffer. The rest will just be thrown away (this happens at the cast from long to uint8_t). This works as long, as the value is between 0 and 127 (which is the upper part of the int8_t value range). With higher (or lower) values your received data will be garbage. Instead you need to write every byte of your data into the buffer:

Wire.write(Distanceincm  &amp; 0x000000FF);
Wire.write((Distanceincm &amp; 0x0000FF00) &gt;&gt; 8);
Wire.write((Distanceincm &amp; 0x00FF0000) &gt;&gt; 16);
Wire.write((Distanceincm &amp; 0xFF000000) &gt;&gt; 24);


With bitwise ANDing (&amp;) of the hexadecimal value 0x000000FF, we are deleting all bits, beside the least significant byte (analog with 0x0000FF00 for the second least significant byte, and so on). Then we are shifting the corresponding byte to the position of the least significant byte (8 bits for the seconds least significant byte, 16 bits for the third least significant byte, and so on), which then gets used by Wire.write(). To better understand this, read about bitwise operators on the web.

You have to send both integer values in a similar fashion (though they both have only 2 bytes instead of 4).
Now that we are sending more bytes, we also need to receive and read all these bytes correctly. First we need to request the correct number of bytes. 4 bytes for the long value and 2 bytes for both int values --> 8 bytes. So you need to request 8 bytes:

Wire.requestFrom(4, 8);


Then you need to read these bytes into the corresponding variables:

long distance = Wire.read()
                | (Wire.read() &lt;&lt; 8)
                | (Wire.read() &lt;&lt; 16)
                | (Wire.read() &lt;&lt; 24);


We are using the bitwise OR (|) to put the bytes together, shifting every byte to its correct position in the long value. In a similar way you are putting together the 2 int values.