问题
I am writing ESME using logica smpp lib, but have a serious problem - when SMSC send to ESME [FIN, ACK], ESME do not answer correct.
Here TCP dump:
2751.016216 ESME -> SMSC SMPP SMPP Submit_sm
2751.019818 SMSC -> ESME SMPP SMPP Submit_sm - resp: "Throttling error (ESME exceeded allowed message limits)"
2751.136172 ESME -> SMSC TCP 42265 > 5001 [ACK] Seq=1651885221 Ack=3959508692 Win=123 Len=0
2774.588453 SMSC -> ESME TCP 5001 > 42265 [FIN, ACK] Seq=3959508692 Ack=1651885221 Win=32768 Len=0
2774.741502 ESME -> SMSC TCP 42265 > 5001 [ACK] Seq=1651885221 Ack=3959508693 Win=123 Len=0
2821.032427 ESME -> SMSC SMPP SMPP Submit_sm
2821.033502 SMSC -> ESME TCP 5001 > 42265 [RST] Seq=3959508693 Ack=0 Win=32768 Len=22
How to solve this? Is it possible to handle this packet?
回答1:
In class TCPIPConnection
, method - public ByteBuffer receive()
you should do something like this:
bytesRead = inputStream.read(receiveBuffer, 0, bytesToRead);
if (bytesRead == -1){
//close connection here
}
回答2:
The whole point of using a framework / Library like Logica lib should be to isolate you from low level API / TCP FIN level details, otherwise there is no value add from using the framework. We have been through this route, and unless you have talented TCP programmers, this route of working at the TCP level is not going to be productive.
I have seen opensource SMPP lib Cloudhopper (made by Twitter and later open sourced) being used in a very large platforms since years. It is robust and production proven in many leading Telcos. It has sample clients which you can use to customize. Connection management: Cache the connection the first time you have a SMPP connection (per session). On doing a submitSM PDU(send the SMS), check the type of Exception, it it is connection exception, simply re-bind and re-int the SMPP session / Connection. If you have large periods of in-activity ( say more than 40 seconds), SMPP servers/SMSC on thier end may throw away the connection. To re-connect you have two options: a) Detect the stale connection next time you do a submitSM PDU, reconnect, update the cache and then send the submitSm PDU or b) This is the preferred option. Have a separate thread which does a enquireLink pDU periodically - say every 45 seconds, this will make sure the connection remains active.The assumption is that the enquireLink and submitSM PDU use the same cached SMPP session / Connection. Of course if the enquireLink PDU detects a broken connection , it should do a re-bind and update the common SMPP session / connection. I have seen this approach working nicely in multiple applications since years.
来源:https://stackoverflow.com/questions/9839058/correct-closing-tcp-connection-throw-java