When I learned about distributed file systems, I downloaded the source code of moosefs and conducted a simple test. I found that the implementation efficiency of Moose is not bad. When I read the source code of the reader, I found that it encapsulated the C socket interface, the related files are saved. I was idle yesterday. I want to test this socket interface. During the test of UDP, I found that the server cannot correctly return information to the client after receiving the data.
After reading the code to find problems, the udpread function implements the following udpread:
Int udpread (INT sock, uint32_t ADDR, void * buff, uint16_t Leng)
{
If (ADDR> addrlen) Return-1;
If (ADDR = 0 xffffffff) {// ignore peer name
Return recvfrom (sock, buff, Leng, 0, (struct sockaddr *) null, 0 );
} Else {
Socklen_t templeng;
Struct sockaddr tempaddr;
Return recvfrom (sock, buff, Leng, 0, & tempaddr, & templeng );
If (templeng = sizeof (struct sockaddr_in )){
Addrtab [ADDR] = * (struct sockaddr_in *) & tempaddr );
}
}
}
1st, 3, and 4 parameters are easy to understand. The second parameter is the number of an address pool. In this socket implementation, the frequently used struct sockaddr structure is put into a memory pool (addrtab) when this structure is required, it is obtained directly from the memory pool and the number of the address in the address pool is returned.
The second parameter ADDR is the number of a struct sockaddr in the address pool. This number is passed in. udpread fills the address of the other end into the sockaddr structure of the corresponding number. However, in the udpread implementation of this version, after recvfrom is executed, it will return directly, and the subsequent filling steps are not carried out. After I make the modification, the UDP server runs normally.
Originally wanted to report this problem moosefs author, under the new version of the source code (mfs-1.6.15), found that the bug has been corrected, the corrected code is:
Int udpread (INT sock, uint32_t * IP, uint16_t * port, void * buff, uint16_t Leng ){
Socklen_t templeng;
Struct sockaddr tempaddr;
Struct sockaddr_in * saptr;
Int ret;
Ret = recvfrom (sock, buff, Leng, 0, & tempaddr, & templeng );
If (templeng = sizeof (struct sockaddr_in )){
Saptr = (struct sockaddr_in *) & tempaddr );
If (IP! = (Void *) 0 ){
* IP = ntohl (saptr-> sin_addr.s_addr );
}
If (port! = (Void *) 0 ){
* Port = ntohs (saptr-> sin_port );
}
}
Return ret;
}
You must be skeptical about the resources on the Network (Principles and source code). Otherwise, you will not be able to understand the wrong knowledge. It is better to believe in books than to have no books, what you realize is the best.