Udp error packets. See the following code $ wordHELLO; $ confarray (array (ip10.1.146.20., port2001), array (ip10.1.146.20., port2002); functionudpGet ($ word, $ ip, $ port) {$ socksocke problem
See the following code.
$ Word = 'hello ';
$ Conf = array (
Array ('IP' => '10. 1.146.20.', 'port' => 2001 ),
Array ('IP' => '10. 1.146.20.', 'port' => 2002)
);
Function udpGet ($ word, $ ip, $ port)
{
$ Sock = socket_create (AF_INET, SOCK_DGRAM, SOL_UDP );
Socket_set_option ($ sock, SOL_SOCKET, SO_SNDTIMEO, array ('SEC '=> 2, 'usec' => 0 ));
Socket_set_option ($ sock, SOL_SOCKET, SO_RCVTIMEO, array ('SEC '=> 2, 'usec' => 0 ));
Socket_sendto ($ sock, $ word, strlen ($ word), 0x100, $ ip, $ port );
Socket_recvfrom ($ sock, $ Results, 8192, 0, $ host, $ port );
Socket_close ($ sock );
Return $ result;
}
For ($ I = 0; $ I <2; $ I ++)
{
$ Res = udpGet ($ word, $ conf [$ I] ['IP'], $ conf [$ I] ['port']);
Var_dump ($ res );
}
That is, the UPD is used continuously to send and receive data to two servers (to illustrate the problem, the server here uses the simplest callback logic ),
If the process is normal, the client will receive 'hello' twice '. But what if a problem occurs on the service end?
Currently, the client timeout time is 2 seconds. assume that data is sent 3 seconds after Port 2001, and Port 2002 cannot be used,
Guess what the result will be? "Two NULL !", Intuitively, this is the answer. If you think so,
Congratulations! the answer is wrong.
The actual answer is:
NULL
String (5) "HELLO"
Analysis
Use tcpdump to capture packets. the following result is displayed:
(133 is the server, 163 is the client, the php version 5.3.1 on the client, and the Linux kernel 2.6.16 on the client)
12:01:39. 014658 IP 10.1.146.163.40678> 10.1.146.133.2001: UDP, length 5
12:01:41. 015121 IP 10.1.146.163.40678> 10.1.146.133.2002: UDP, length 5
12:01:42. 016103 IP 10.1.146.133.2001> 10.1.146.163.40678: UDP, length 5
In my opinion, two requests should be sent and received using different temporary ports, but from the packet capture results,
Although the client performs socket_create twice, the same temporary port (40678) is actually used)
Send and receive data! This enables the second request to receive the response packet of the first request.
It seems that this is a system BUG. The experiment found that this problem only exists in some systems,
For example, Linux kernel 2.6.32 + php5.2.3 does not have this problem.
Solution
Specify the socket port each time for sending and receiving. The following red code is displayed.
$ Sock = socket_create (AF_INET, SOCK_DGRAM, SOL_UDP );
$ SendPort = rand (10240,600 00 );
Socket_bind ($ sock, '10. 1.146.163 ', $ sendPort );
Socket_set_option ($ sock, SOL_SOCKET, SO_SNDTIMEO, array ('SEC '=> 2, 'usec' => 0 ));
Socket_set_option ($ sock, SOL_SOCKET, SO_RCVTIMEO, array ('SEC '=> 2, 'usec' => 0 ));
Of course, the rand port may also have a collision, but after all, this probability is not big and can solve the problem to a large extent.
If you have a better solution, please feel free to contact us ~
0 2
0 2
Refer to the following code $ word = HELLO; $ conf = array (ip = 10.1.146.large, port = 2001), array (ip = 10.1.146.large, port = 2002 )); function udpGet ($ word, $ ip, $ port) {$ sock = socke...