Analysis of connection reset Exception Handling in java

Source: Internet
Author: User
Tags signal handler socket error connection reset

Several connection rest exceptions, Broken pipe, Connection reset, connection reset by peerSocked reset case in Linux there will be two common sock reset error codes ECONNRESET this error is described as "connection reset by peer", that is, "reset Connection of the other party ", this usually occurs when the service process is terminated earlier than the customer process. When a service process is terminated, it will send a FIN Shard to the customer TCP. The customer TCP responds to ACK and the service TCP will be transferred to the FIN_WAIT2 status. At this time, if the customer process does not process the FIN (such as blocking other calls without closing the Socket), the customer TCP will be in the CLOSE_WAIT state. When the customer process sends data to the FIN_WAIT2 service TCP again, the Service TCP will immediately respond to the RST. In general, this situation can also lead to another application exception. After a customer process sends data, it often waits for the network IO to receive data, such as read or readline calls, in this case, due to the execution sequence, if the call is executed before the RST node is received, the customer process will receive an unexpected EOF error. In this case, the error "server terminated prematurely"-"server premature termination" is usually output. The EPIPE error is described as "broken pipe", that is, "pipeline cracking". This usually occurs when the client process ignores (or fails to handle it in time) the Socket error, when more data is written to the service TCP, the kernel sends the SIGPIPE signal to the client process. By default, the process is terminated (at this time, the front-end process does not perform core dump ). According to the preceding ECONNRESET error, writing data to a FIN_WAIT2 service TCP (with an ACK response to the FIN shard) is not a problem, but writing a Socket that has received the RST is an error. Processing of socket input stream/output stream in Java first looks at the code snippet SocketInputStream. c [cpp] switch (errno) {case ECONNRESET: case EPIPE: JNU_ThrowByName (env, "sun/net/ConnectionResetException", "Connection reset"); break ;.... socketOutputStream. c [cpp] if (errno = ECONNRESET) {JNU_ThrowByName (env, "sun/net/ConnectionResetException", "Connection reset");} else {NET_ThrowByNameWithLastError (env, "java/net/Socke TException "," Write failed ");} You can see that the read and Write operations in java are different in EPIPE processing. In read operations, all resets throw ConnectionResetException, the error message is that Connection Reset throws ConnectionResetException for ECONNRESET while write, while SocketException is thrown for EPIPE, the error message is how the Broken pipe prints the message: Broken pipeSIGPIPE signal processing function. After receiving the reset package, if the socket is read, the error EPIPE occurs, at the same time, we often receive the SIGPIPE signal. in the program, we can see that if java does not perform write operations, the error EPIPE is not processed, the exception thrown at the beginning is thrown by the signal processing function. First, let's take a look at the signal SIGPIP. E's processing function. In Linux: install_signal_handlers, call the function [cpp] set_signal_handler (SIGSEGV, true); set_signal_handler (SIGPIPE, true); set_signal_handler (SIGBUS, true ); set_signal_handler (SIGILL, true); handler (SIGFPE, true); set_signal_handler (SIGXFSZ, true); and set_signal_handler, the corresponding signal processing function is signalHandler [cpp] sigAct. sa_handler = SIG_DFL; if (! Set_installed) {sigAct. sa_flags = SA_SIGINFO | SA_RESTART;} else {sigAct. sa_sigaction = signalHandler; sigAct. sa_flags = SA_SIGINFO | SA_RESTART;} finally called the JVM_handle_linux_signal function in the X86 architecture. The JVM_handle_linux_signal [cpp] extern "C" int handler (int sig, siginfo_t * info, void * ucVoid, int abort_if_unrecognized) {ucontext_t * uc = (ucontext_t *) ucVoid; Thread * t = ThreadLocalStorage: ge T_thread_slow (); SignalHandlerMark shm (t); // Note: it's not uncommon that JNI code uses signal/sigset to install // then restore certain signal handler (e.g. to temporarily block SIGPIPE, // or have a SIGILL handler when detecting CPU type ). when that happens, // JVM_handle_linux_signal () might be invoked with junk info/ucVoid. to // avoid unnecessary crash when libjsig is not preloaded, try hand Le signals // that do not require siginfo/ucontext first. if (sig = SIGPIPE | sig = SIGXFSZ) {// allow chained handler to go first if (OS: Linux: chained_handler (sig, info, ucVoid )) {return true;} else {if (PrintMiscellaneous & (WizardMode | Verbose) {char buf [64]; warning ("Ignoring % s-see bugs 4229104 or 646499219 ", OS: exception_name (sig, buf, sizeof (buf);} return true ;}}...} The chained handler is used for signal SIGPIPE processing, that is, the original signal processing function of the system is used, this proves that the exception is not the NET_ThrowByNameWithLastError function thrown by the signal processing function. Since it is not an exception thrown by the signal processing function, continue to view the original outputstream program [cpp] if (errno = ECONNRESET) {JNU_ThrowByName (env, "sun/net/ConnectionResetException", "Connection reset");} else {NET_ThrowByNameWithLastError (env, "java/net/SocketException ", "Write failed");} is the case of else, so for EPIPE errors, the socketexception thrown by java, the error message is Write f Ailed, in fact we can see it is SockedException, the exception is correct, but the information is displayed as Broken pipe, rather than Write failed. the key point is in the function NET_ThrowByNameWithLastError [cpp] void encode (JNIEnv * env, const char * name, const char * defaultDetail) {char errmsg [255]; sprintf (errmsg, "errno: % d, error: % s \ n ", errno, defaultDetail); JNU_ThrowByNameWithLastError (env, name, errmsg);} function JNU_ThrowByNameWithLastError [cpp] JNIEXPORT void JN ICALL JNU_ThrowByNameWithLastError (JNIEnv * env, const char * name, const char * defaultDetail) {char buf [256]; int n = JVM_GetLastErrorString (buf, sizeof (buf )); if (n> 0) {jstring s = JNU_NewStringPlatform (env, buf); if (s! = NULL) {jobject x = JNU_NewObjectByName (env, name, "(Ljava/lang/String;) V", s); if (x! = NULL) {(* env)-> Throw (env, x) ;}} if (! (* Env)-> ExceptionOccurred (env) {JNU_ThrowByName (env, name, defaultDetail);} the program displays information about JVM_GetLastErrorString first, if the information is empty, the defaultDetail exception information is displayed, that is, the corresponding Write failed! JVM_GetLastErrorString uses hpi: lasterror, that is, the function sysGetLastErrorString is the same [cpp] int sysGetLastErrorString (char * buf, int len) {if (errno = 0) in linux and solaris) {return 0;} else {const char * s = strerror (errno); int n = strlen (s); if (n> = len) n = len-1; strncpy (buf, s, n); buf [n] = '\ 0'; return n ;}} it turns out to be strerror (errno ), that is, the error message corresponding to the error number of linux kernel is displayed. Conclusion: Broken pipe is the error message corresponding to the kernel, not the information provided by java itself.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.