Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 套接字连接重置仍然无法理解_Java_Multithreading_Sockets - Fatal编程技术网

Java 套接字连接重置仍然无法理解

Java 套接字连接重置仍然无法理解,java,multithreading,sockets,Java,Multithreading,Sockets,问题是: 看起来,基于Java套接字的服务器程序在建立连接的过程中错误地重置了与基于Java套接字的客户端的连接,尽管数据传输的超时设置被设置为“无限” 我在以下设备上测试了服务器: Linux Ubuntu 14.04 LTS内核3.13.0-29-通用Java(TM)SE运行时环境(build 1.7.0_03-b04) 等等 Windows 8.1版本6.3.9600 Java(TM)SE运行时环境(build 1.7.0_51-b13) 这是有区别的。在Windows上,当所有线程都很忙

问题是:

看起来,基于Java套接字的服务器程序在建立连接的过程中错误地重置了与基于Java套接字的客户端的连接,尽管数据传输的超时设置被设置为“无限”

我在以下设备上测试了服务器:

Linux Ubuntu 14.04 LTS内核3.13.0-29-通用Java(TM)SE运行时环境(build 1.7.0_03-b04) 等等 Windows 8.1版本6.3.9600 Java(TM)SE运行时环境(build 1.7.0_51-b13)

这是有区别的。在Windows上,当所有线程都很忙并且使用了backlog时,服务器不接受连接,因此应该如此。在Linux连接被接受的情况下,数据可以被写入和刷新(除了TCP_NODELAY),但是在客户端的后续读取时,它会不时收到“连接重置”。我在服务器端没有异常。 如果客户端在Windows或Linux下运行,则行为不会发生变化,在环回地址、本地网络地址或外部网络地址上运行服务器也不会有任何区别

欢迎提供任何帮助或贡献。我也是来学习的,所以如果我犯了编码错误,就告诉我

在之前的文章中,除了我网站上的JAR链接和源图片外,没有添加任何源代码。我同意这在这里是不常见的,所以我制作了一个简明的版本,它也揭示了这个问题。请注意,故意选择所有设置以使服务器处于过载状态,并将连接和读取超时设置为“无限”。我确实意识到,这些并不是人们在“现实生活”中会选择的,而仅仅是为了产生“连接重置”

这是客户端的代码:

package resetconntest;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.Semaphore;

class MiniClient {

  static boolean SHOW_EXC_ONLY = true;   // show exceptions only
  static int     THREADS       = 64;     // number of "simultaneous connections"
  static int     LOOPS         = 256;    // total number of connections
  static String  HOST          = "192.168.0.10"; // server hostname 
  static int     PORT          = 7272;           // server port
  static int     CONN_TIMEOUT  = 0;      // keep infinite connect time for test
  static int     SO_TIMEOUT    = 0;      // keep infinite read    time for test
  static int     SO_LINGER     = -1;     // no linger
  static boolean REUSE_ADDRESS = false;  // chosen for test
  static boolean TCP_NODELAY   = true;   // small blocks, so no Nagle 
  static boolean KEEP_ALIVE    = false;  // chosen for test
  static int     TRAFFIC_CLASS = 0;      // if used, use mask as for ToS

  public static void main ( String[] args ) {
    new MiniClient().runTest ();
    System.exit ( 0 );
  }

  MiniClient () {}

  void runTest () {
    Object syncer = new Object();
    System.out.println ( "--> start MiniClient" );
    try {
      Semaphore semaphore = new Semaphore ( THREADS );
      for ( int x = 0 ; x < LOOPS ; x++ ) {
        semaphore.acquireUninterruptibly ();
        new Requester ( syncer ,x + 1 ,semaphore ).start(); 
      }
      while ( semaphore.availablePermits() < THREADS ) {
        Thread.sleep ( 100 );
      }
    } catch ( Throwable anyThrown ) {
      synchronized ( syncer ) {
        System.out.println ( "--> throwable in main" );
        anyThrown.printStackTrace ( System.out );
        System.out.println ( "<-- throwable in main" );
      }
    }
    System.out.println ( "<-- end MiniClient" );
  }

  class Requester extends Thread {
    Object    syncer;
    String    index;
    Semaphore semaphore;

    Requester ( Object syncer ,int index ,Semaphore semaphore ) {
      this.syncer    = syncer;
      this.index     = Integer.toString ( index );
      this.semaphore = semaphore;
    }

    public void run () {
      try {
        Socket socket = new Socket ();
        socket.connect         ( new InetSocketAddress ( HOST ,PORT ) ,CONN_TIMEOUT );
        socket.setSoTimeout    ( SO_TIMEOUT );
        socket.setSoLinger     ( (SO_LINGER >= 0) ,SO_LINGER );
        socket.setReuseAddress ( REUSE_ADDRESS );
        socket.setTcpNoDelay   ( TCP_NODELAY );
        socket.setKeepAlive    ( KEEP_ALIVE );
        if ( TRAFFIC_CLASS != 0 ) socket.setTrafficClass ( TRAFFIC_CLASS );
        PrintWriter    out = new PrintWriter    ( new OutputStreamWriter ( socket.getOutputStream() ) );
        BufferedReader in  = new BufferedReader ( new InputStreamReader  ( socket.getInputStream()  ) );

        if ( dialog ( "aaaaa" ,out ,in ) )
        if ( dialog ( "bbbbb" ,out ,in ) )
             dialog ( "close" ,out ,in );

        socket.shutdownInput();
        socket.shutdownOutput();
        in.close();
        out.close();
        socket.close ();
      } catch ( Throwable anyThrown ) {
        synchronized ( syncer ) {
          System.out.println ( "--> throwable in client thread:" + index );
          anyThrown.printStackTrace ( System.out );
          System.out.println ( "<-- throwable in client thread:" + index );
        }
      }
      semaphore.release ();
    }

    boolean dialog ( String         text
                    ,PrintWriter    out 
                    ,BufferedReader in ) throws Throwable {
      String msg = index + ':' + text;
      try {
        if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "--> send: " + msg ); }
        out.println ( msg );
        out.flush();
        String resp = in.readLine();
        if ( resp == null ) {
          synchronized ( syncer ) { System.out.println ( "<-- got EOF after: " + msg ); }
          return false;
        }
        if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "<-- received: " + resp ); }
      } catch ( Throwable anyThrown ) {
        synchronized ( syncer ) {
          System.out.println ( "--> throwable in client thread:" + index );
          System.out.println ( "--> at processing message: " + msg );
          anyThrown.printStackTrace ( System.out );
          System.out.println ( "<-- at processing message: " + msg );
          System.out.println ( "<-- throwable in client thread:" + index );
        }
        return false;
      }
      return true;
    }
  } // end of inner class

} // end of code
package测试;
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.io.OutputStreamWriter;
导入java.io.PrintWriter;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入java.util.concurrent.Semaphore;
类小型客户端{
静态布尔值SHOW\u EXC\u ONLY=true;//仅显示异常
static int THREADS=64;//同时连接数
静态int循环=256;//连接总数
静态字符串HOST=“192.168.0.10”;//服务器主机名
静态int-PORT=7272;//服务器端口
static int CONN_TIMEOUT=0;//为测试保留无限连接时间
static int SO_TIMEOUT=0;//为测试保留无限的读取时间
static int SO_LINGER=-1;//无LINGER
静态布尔重用_ADDRESS=false;//选择用于测试
静态布尔值TCP_NODELAY=true;//小块,所以没有Nagle
静态布尔KEEP_ALIVE=false;//选择用于测试
static int TRAFFIC_CLASS=0;//如果使用,请将掩码用作ToS
公共静态void main(字符串[]args){
新的MiniClient().runTest();
系统出口(0);
}
小型客户端(){}
无效运行测试(){
对象同步器=新对象();
System.out.println(“-->start MiniClient”);
试一试{
信号量信号量=新信号量(线程);
for(int x=0;xthrowable in main”);
anythround.printStackTrace(System.out);
System.out.println(“可在客户端线程中丢弃:”+索引);
anythround.printStackTrace(System.out);
System.out.println(“发送:+msg);}
out.println(msg);
out.flush();
字符串resp=in.readLine();
如果(resp==null){
synchronized(syncer){System.out.println(“在处理消息时:“+msg”);
anythround.printStackTrace(System.out);
System.out.println(“启动迷你服务器”);
试一试{
InetSocketAddress socketAddress=新的InetSocketAddress(InetAddress.getByName(主机),端口);
ServerSocket ServerSocket=newserversocket();
serverSocket.bind(socketAddress,BACKLOG);
serverSocket.setReuseAddress(重用服务器地址);
serverSocket.SetSortimeout(ACC_超时);
信号量信号量=新信号量(线程);
接受套接字;
while(true){
信号量。获取不间断();
accepted=serverSocket.accept();
新服务程序(同步器、已接受、信号量).start();
}
//从未到达,在服务器构造时发出警告。
//要结束服务器,只需使用老式的钝器CTRL-C
//while(semaphore.availablePermits()throwable in main”);
anythround.printStackTrace(System.out);
System.out.println(“可在服务器线程中丢弃”);
anythround.printStackTrace(System.out);
System.out.println(“

在服务器和客户机上完全删除这一行。除了我在评论中所说的之外,这是引发连接重置的另一种方式。只需删除它。你不需要它。这是一个问题,不是一个解决方案。

除非你有特定问题,否则你的帖子不在本网站的范围内。你能解释一下原因吗?我刚刚有一个Java编程专业人士我口头描述的问题。我看到许多人的帖子与我处理的问题有着相同的问题类型。你的问题以目前的形式无法回答。它包括对你认为应用程序的功能的描述,以及一个指向大量没有人会遵循的场外代码的链接。这不是免费调试g服务
package resetconntest;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Semaphore;

class MiniServer {

  static boolean SHOW_EXC_ONLY        = false;  // show messages and exceptions
  static String  HOST                 = "192.168.0.10";  // host name   binded to
  static int     PORT                 = 7272;            // port number binded to 
  static int     ACC_TIMEOUT          = 0;      // keep timeout for accept infinite for test
  static boolean REUSE_SERVER_ADDRESS = false;  // chosen for test
  static int     BACKLOG              = 2;      // keep low for test
  static int     THREADS              = 8;      // keep low for test
  static int     SO_TIMEOUT           = 0;      // keep infinite read timeout for test
  static int     SO_LINGER            = -1;     // no lingering
  static boolean REUSE_ACC_ADDRESS    = false;  // chosen for test
  static boolean TCP_NODELAY          = true;   // small blocks, so no Nagle
  static boolean KEEP_ALIVE           = false;  // chosen for test
  static int     TRAFFIC_CLASS        = 0;      // if used, use mask as for ToS
  static int     PROCESS_DELAY        = 500;    // simulate long message processing 0.5 sec

  public static void main ( String[] args ) {
    new MiniServer().runTest ();
    System.exit ( 0 );
  }

  MiniServer () {}

  public void runTest () {
    Object syncer = new Object();
    System.out.println ( "--> start MiniServer" );
    try {
      InetSocketAddress socketAddress = new InetSocketAddress ( InetAddress.getByName ( HOST ), PORT );
      ServerSocket      serverSocket  = new ServerSocket ();
      serverSocket.bind            ( socketAddress ,BACKLOG );
      serverSocket.setReuseAddress ( REUSE_SERVER_ADDRESS );
      serverSocket.setSoTimeout    ( ACC_TIMEOUT );
      Semaphore semaphore = new Semaphore ( THREADS );
      Socket    accepted;
      while ( true ) {
        semaphore.acquireUninterruptibly();
        accepted = serverSocket.accept();
        new Servicer ( syncer ,accepted ,semaphore ).start(); 
      }
      // never reached, gives the warning at server construction.
      // to end the server, just use the old fashioned blunt CTRL-C
      // while ( semaphore.availablePermits() < THREADS ) {
      //   Thread.sleep ( 100 );
      // }
      // serverSocket.close ();
    } catch ( Throwable anyThrown ) {
      synchronized ( syncer ) {
        System.out.println ( "--> throwable in main" );
        anyThrown.printStackTrace ( System.out );
        System.out.println ( "<-- throwable in main" );
      }
    }
    System.out.println ( "<-- end MiniServer" );
  }

  class Servicer extends Thread {
    Object    syncer;
    Socket    socket;
    Semaphore semaphore;

    Servicer ( Object    syncer
              ,Socket    socket
              ,Semaphore semaphore ) { 
      this.syncer    = syncer;
      this.socket    = socket;
      this.semaphore = semaphore;
    }

    public void run () {
      try {
        socket.setSoTimeout    ( SO_TIMEOUT );
        socket.setSoLinger     ( (SO_LINGER >= 0) ,SO_LINGER );
        socket.setReuseAddress ( REUSE_ACC_ADDRESS );
        socket.setTcpNoDelay   ( TCP_NODELAY );
        socket.setKeepAlive    ( KEEP_ALIVE );
        if ( TRAFFIC_CLASS != 0 ) socket.setTrafficClass ( TRAFFIC_CLASS );
        BufferedReader in =  new BufferedReader( new InputStreamReader  ( socket.getInputStream()  ) );
        PrintWriter    out = new PrintWriter   ( new OutputStreamWriter ( socket.getOutputStream() ) );
        String         clientMessage;
        while ( true ) {
          clientMessage = in.readLine ();
          if ( clientMessage == null ) {
            synchronized ( syncer) { System.out.println ( "<-> received end of file from accepted socket" ); }
            break;
          }
          if ( SHOW_EXC_ONLY == false ) synchronized ( syncer ) { System.out.println ( "client said: " + clientMessage ); }
          if ( PROCESS_DELAY > 0 ) Thread.sleep ( PROCESS_DELAY );
          out.println ( "echo: " + clientMessage );
          out.flush();
          if ( clientMessage.indexOf ( "close" ) >= 0 ) break;
        }
        socket.shutdownInput();
        socket.shutdownOutput();
        in.close();
        out.close();
        socket.close();
      } catch ( Throwable anyThrown ) {
        synchronized ( syncer ) {
          System.out.println ( "--> throwable in server thread" );
          anyThrown.printStackTrace ( System.out );
          System.out.println ( "<-- throwable in server thread" );
        }
      }
      semaphore.release();
    }

  } // end of inner class

} // end of code
socket.setSoLinger( (SO_LINGER >= 0) ,SO_LINGER );