Java 无法从服务器读取响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9687153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:09:02  来源:igfitidea点击:

Can not read response from server

javamysqljdbc

提问by Pita

I have written a Java Program and the program connects to a database on my server, to find records, write records, update and delete. for some reason finding records works, but most of the time when i try to save or write a record it gives an error message saying:

我编写了一个 Java 程序,该程序连接到我服务器上的数据库,以查找记录、写入记录、更新和删除。出于某种原因,查找记录是有效的,但大多数情况下,当我尝试保存或写入记录时,它会给出一条错误消息:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 9,787 milliseconds ago.       The last packet sent successfully to the server was 8,183 milliseconds ago.

Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more

Can anyone explain why this is happening? Usuually this gives me the error message when trying to add a record, after i had the software running for more than about half a minute. seems to loose connection or something. when i run the program and quickly write a new record, it works

谁能解释为什么会这样?通常,在我让软件运行超过大约半分钟后,当我尝试添加记录时,这会给我错误消息。似乎连接松动什么的。当我运行程序并快速写入新记录时,它可以工作

回答by ChapMic

Did you follow/read this tutorial :

您是否遵循/阅读了本教程:

Connectivity with MYSQL

与 MYSQL 的连接

You have a part for your exception which can be useful for you.

您有一部分可以用于您的例外情况,这对您有用。

I will quote something about your specific exception, just try that :

我将引用有关您的特定例外的一些内容,请尝试:

If you get a SQLException: Connection refused or Connection timed out or a MySQL specific CommunicationsException: Communications link failure, then it means that the DB isn't reachable at all. This can have one or more of the following causes:

IP address or hostname in JDBC URL is wrong. Hostname in JDBC URL is not recognized by local DNS server. Port number is missing or wrong in JDBC URL. DB server is down. DB server doesn't accept TCP/IP connections. DB server has run out of connections. Something in between Java and DB is blocking connections, e.g. a firewall or proxy.

To solve the one or the other, follow the following advices:

Verify and test them with ping. Refresh DNS or use IP address in JDBC URL instead. Verify it based on my.cnf of MySQL DB. Start the DB. Verify if mysqld is started without the --skip-networking option. Restart the DB and fix your code accordingly that it closes connections in finally. Disable firewall and/or configure firewall/proxy to allow/forward the port.

如果您收到 SQLException: Connection denied 或 Connection timed out 或 MySQL 特定的 CommunicationsException: Communications link failure,则意味着根本无法访问数据库。这可能有以下一种或多种原因:

JDBC URL 中的 IP 地址或主机名错误。本地 DNS 服务器无法识别 JDBC URL 中的主机名。JDBC URL 中的端口号丢失或错误。数据库服务器已关闭。数据库服务器不接受 TCP/IP 连接。数据库服务器的连接用完了。Java 和 DB 之间的某些东西正在阻止连接,例如防火墙或代理。

要解决其中之一,请遵循以下建议:

用 ping 验证和测试它们。刷新 DNS 或改用 JDBC URL 中的 IP 地址。根据 MySQL DB 的 my.cnf 进行验证。启动数据库。验证是否在没有 --skip-networking 选项的情况下启动了 mysqld。重新启动数据库并相应地修复您的代码,最终关闭连接。禁用防火墙和/或配置防火墙/代理以允许/转发端口。

回答by ashish

Sometimes this problem comes due to size of system RAM.May be you are inserting the data using buffer through RAM. To get out of this problem.

有时这个问题是由于系统 RAM 的大小引起的。可能是您通过 RAM 使用缓冲区插入数据。为了摆脱这个问题。

  1. Set the Auto commit disable before inserting the data.
  2. insert some amount of data appropriate to your System RAM (not the whole).
  3. Commit the query.
  4. Do the steps 2 and 3 again until the whole insertion will not be done.
  1. 在插入数据之前设置自动提交禁用。
  2. 插入一些适合您的系统 RAM(不是全部)的数据。
  3. 提交查询。
  4. 再次执行第 2 步和第 3 步,直到无法完成整个插入。

You can understand this by the following code.

您可以通过以下代码理解这一点。

public static void main(string args[]) 
{
  Connection con = null;
  Statement stm = null;
  int i;
  float ratio;
  ratio=1.0f;
  try
  {
    Class.forName("com.mysql.jdbc.Driver");
    // Connecting to the database
    con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
                                      "ashish", "impetus");
    File f = new File("filler"); // taking the random text data from the file
                                 // filler.txt and inserting that string
                                 // in filler field of the relations
    RandomAccessFile r = new RandomAccessFile(f,"r");
    Random randomGenerator = new Random();
    String strLine=new String();
    int r1,flag=0;
    stm = con.createStatement();
    con.setAutoCommit(false) ;

    int k=0;
    i=0;                

    long sum2=0;
    while(k%50000==0)
    {
      final long start = currentTimeMillis();
      final StringBuilder builder =
        new StringBuilder("INSERT INTO accounts 
                           (aid, bid,abalance,filler) VALUES ");
      while(i!=naccounts*ratio*scale )
        {
        int j=i+1;
        for(int l=0;l<40;l++)
        {
          strLine+=((char)r.read());
          r.skipBytes(0);
        }
        r1=randomGenerator.nextInt(1500);
        if(strLine.equals(""))
        {
          flag=1;
        }
        if(flag!=1)
        {   
          strLine=strLine.replaceAll("\s","");
          strLine=strLine.replaceAll("\t","");
        }                   
        flag=0;
        if (i%50000!=0) 
        {
          builder.append(",");
        }
        builder.append(format("(%s, %s, %s, '%s')", j, 
                       i/naccounts+1, 0, strLine));
        strLine="";
        r.seek(r1);
        i++;
        if(i%50000==0||i>=naccounts*ratio*scale)
        {   
          final String query = builder.toString();
          final PreparedStatement statement1 = con.prepareStatement(query);
          statement1.execute();
          con.commit();
          final long stop= currentTimeMillis();
          sum2=sum2+(stop-start);
          statement1.close();
        }
        if(i%50000==0||i>=naccounts*ratio*scale)
        {
          break;
        }
      }
      k=k+50000;
      if(k>naccounts*ratio*scale)
      {
        break;
      }
    }
    System.out.println(i+" rows inserted accounts table ");
    System.out.println("time taken = "+sum2+" milliseconds");
  }
  catch (SQLException e)
  {
    System.out.println("Connection Failed! Check output console");
    e.printStackTrace();
    return;
  }
  catch (Exception e) 
  {
    e.printStackTrace();
  }
}

回答by jidnesh

I was having the same sort of issue. I referred many post and comments but the thing worked for me was changing some parameters of the my.cnffile. Hope it will help you also ....

我遇到了同样的问题。我提到了许多帖子和评论,但对我有用的是更改my.cnf文件的一些参数。也希望能帮到你......

Set following parameters in my.cnf [mysqld]section

my.cnf [mysqld]部分设置以下参数

interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"

wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"

max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"

skip-name-resolve # "Don't resolved host names. All host names are IP's"