Send blocking
The socket recv send interface is blocked, which causes the server side not to respond to any requests from the client, so the socket is set to a non-blocking state in general.
However, some scenarios, such as ssl_accept, need to use a blocked socket, or the handshake is very easy to fail, but has been blocked, prone to server-side DOS phenomenon.
Here is the explanation of the blockage http://blog.csdn.net/xiaofei0859/article/details/6037814
For example, if you call the Send function to send a certain byte, the work done inside the system is actually just transferring data (Copy) to the output buffer of the TCP/IP stack, it does not mean that the data has been successfully sent out, if tcp/ The IP stack does not have enough buffers available to hold the data you copied ... This is the difference between blocking and non-blocking: the socket send function for blocking mode will not return until the system buffer has enough space to copy the data you want to send. For a nonblocking socket, send returns immediately wsaewoulddblock tells the caller, "the send operation is blocked!!! You have to deal with it ... "
For the RECV function, the internal working mechanism of the function is actually waiting for the TCP/IP protocol stack to notify the receiving buffer that it says: Hi, your data is coming. For a blocking mode socket, if the TCP/IP protocol stack's receive buffer does not notify a result to it, it never returns: Consuming system resources .... For a non-blocking socket, the function returns immediately, and then tells you: Wsaewoulddblock---"No data now, look back."
recv Blocking Construction method
The server-side calls the Recv interface, and if the content is not read, it goes into a blocking state and the process is blocked.
For ssl_accept will call Recv interface, require reading a certain length of content, length is greater than 1, read the content is not enough, then into the blocking state,
The client script can then be constructed, after the connection is established, after a byte is sent, the content begins to be read, which forms a deadlock with the server-side recv.
The client waits for the server side to send data, and the server is blocked from waiting for the content because it is not reading enough.
Lua Socket Script:
Socket =require "Socket"Print(socket.)_version)LocalAddress ="192.168.1.1"LocalPort =443LocalClient =assert(Socket.connect (address, port))if Nil~= Client ThenClient:send ("1") Print("Send to receive!!!!") LocalR = client:receive ("*a") Client:close ()End
Send blocking Construction method
Server side, call the Send interface to send data, when there is not enough space in the buffer, the send interface is in a blocking state,
After the data that waits for the buffer is sent, the cached space can store the data sent by the send, then send activates the return.
After the client is sent to the client Hello data (SSL handshake), the server sends data to the clients, loops around one m of data, but the client does not receive it, and performs a sleep operation:
The following LUA scripting code implements the client, which prepares the ClientHello data, using the Str2bin method, the client does not receive data, sleeps for 3600 seconds using sleep.
Socket =require "Socket"Print(socket.)_version)LocalAddress ="192.168.1.1"LocalPort =443LocalClient =assert(Socket.connect (address, port))--http://m.oschina.net/blog/220844Local functionBin2Hex (s) s=string.gsub(S,"(.)",function(x)return String.Format("%02x",String.byte(x))End) returnsEndLocalH2B = { ["0"] =0, ["1"] =1, ["2"] =2, ["3"] =3, ["4"] =4, ["5"] =5, ["6"] =6, ["7"] =7, ["8"] =8, ["9"] =9, ["A"] =Ten, ["B"] = One, ["C"] = A, ["D"] = -, ["E"] = -, ["F"] = the}Local functionHex2bin (HEXSTR)Locals =string.gsub(Hexstr,"(.) (.)",function(H, L)Print("h=".. H.."l=".. L)--http://www.cnblogs.com/whiteyun/archive/2009/08/07/1540899.htmlh =String.upper(h) L=String.upper(L)return String.char(h2b[h]* -+H2b[l])End) returnsEnd--http://www.cnblogs.com/wcong/p/3218053.htmlrequire("Socket")functionSleep (n) socket.Select(Nil,Nil, N)EndLocalClienthellohexstr =[[1603010200010001fc0301d836e6926224b009080b70496a6515b8cf5a09603e6e309f400ab79fb67225cc203ca2eda02bb49abb6f6dc513684b5df3c C654268108054fe7e28299b03e6bae0002ec02bc02fc00ac009c013c014c012c007c0110033003200450039003800880016002f004100350084000a00 05000401000185ff01000100000a00080006001700180019000b00020100002300a02f1b88ca8fe2638f5d0ae18ed18838f3a4bd7115a8001aeb5dd6a 57d825bf06e98c499eb43763091da9ae0baee573c6ba838b33bf8c4ccf96aff04a1aef0b73a8fb17ba2c1af3bd8a65ef8ff3c90d8f6279139e1cae337 61420cb8daf0d244ad8ca5c0683b442cabafc41463dd23f2365a89ac75856ce6b0e6c224eda9479142f561a8574381667e2a9cafede019ba213cfbfdc a7fa8de776d5e8ba833d2572d33740000001500c200000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000 ]]LocalCleinthelloblock =Hex2bin (CLIENTHELLOHEXSTR);if Nil~= Client Thenclient:send (Cleinthelloblock)Print("Send to receive!!!!") --Local R = client:receive ("*a") --print ("r="): R)Sleep (3600) Print("After Sleep") Client:close ()End
Server-side code, can be completed, can adjust the upper limit of I try:
int i=0; Char " xxx.. xxx"//1034 bytes for (;i<; i++) { 1034 0)}
Blocking avoidance methods
One way is to set the socket to non-blocking mode, this method is the most direct
However, some cases are unacceptable, such as ssl_accept, so there is a second way, excerpted from others ' blogs, to set the socket read or send blocking timeout.
http://idsips.blog.163.com/blog/static/4800127220116611500538/
Linux:structTimeval timeout={3,0};//3s intRet=setsockopt (Sock_fd,sol_socket,so_sndtimeo,&timeout,sizeof(timeout)); intRet=setsockopt (Sock_fd,sol_socket,so_rcvtimeo,&timeout,sizeof(timeout)); IF RET==0is a success,-1 is a failure, you can view errno to determine the cause of the failureintRECVD=RECV (Sock_fd,buf,1024x768,0); if(recvd==-1&&errno==Eagain) {printf ("timeout\n"); }
A method for constructing blocking phenomena of Web server-side recv and send interfaces