我正试图让我的Android应用程序能够写入在计算机上的localhost上运行的MySQL数据库,但是我一直收到Volley超时错误。
几乎所有关于堆栈溢出的解决方案都说要使用stringRequest.setRetryPolicy。正如您在代码中进一步看到的那样,我已经尝试过了,但是不幸的是,这并没有解决问题。我的手机是运行Android版本9的Xiaomi Mi A1。我正在使用WAMP v3.1.7,PHP 7.2,MySQL 5.7和Apache 2.4。
//URL for adding user
public static final String URL_REGISTER = "http://192.168.0.18:3000/pom/add_user.php";
//URL for reading users table
public static final String URL_DB = "http://192.168.0.18/pom/get_all_users.php";
URL_REGISTER是我要用于此请求的URL。下面的功能是发出请求的功能。在单独的课程中。
private void registerUser(final String fname, final String sname, final String phoneno, final String email, final String password){
//tag used to cancel request
String tag_string_req = "req_register";
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.URL_REGISTER,
new Response.Listener<String>(){
@Override
public void onResponse(String response) {
try{
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("Error");
if(error){
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(), "Error occurred: " + errorMsg,
Toast.LENGTH_LONG).show();
}
//Navigate to page that displays DB entries
Intent intent = new Intent(Registration.this, DBView.class);
startActivity(intent);
}catch(JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError error) {
if(error instanceof AuthFailureError){
Log.e(TAG, "Authorisation Failure Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: Authorisation Failure Error", Toast.LENGTH_LONG).show();
}else if(error instanceof NetworkError){
Log.e(TAG, "NetworkError: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: Network Error", Toast.LENGTH_LONG).show();
}else if(error instanceof ParseError){
Log.e(TAG, "Parse Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: Parse Error", Toast.LENGTH_LONG).show();
}else if(error instanceof ServerError){
Log.e(TAG, "Server Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: Server Error", Toast.LENGTH_LONG).show();
}else if(error instanceof TimeoutError){
Log.e(TAG, "Timeout Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: Timeout Error", Toast.LENGTH_LONG).show();
}else if(error instanceof NoConnectionError){
Log.e(TAG, " No Connection Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), "Registration Error: No Connection Error", Toast.LENGTH_LONG).show();
}
}
}){
@Override
protected Map<String, String> getParams(){
//posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("First_name", fname);
params.put("Surname", sname);
params.put("PhoneNo", phoneno);
params.put("Email", email);
params.put("Password", password);
return params;
}
};
strReq.setRetryPolicy(new DefaultRetryPolicy(50000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
//Add to requestQueue
Log.d(TAG, strReq.toString());
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
addToRequestQueue:
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag){
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
add_user:
<?php
/ * *以下代码将创建一个新产品行 *所有产品详细信息均从HTTP发布请求中读取 * /
//create array for json response
$response = array();
//check for required fields
//&& isset($_POST['sname'] && isset($_POST['phoneno']) && isset($_POST['email']) && isset($_POST['password'])
if(isset($_POST['fname'])){
$fname = $_POST['fname'];
$sname = $_POST['sname'];
$phoneno = $_POST['phoneno'];
$email = $_POST['email'];
$password = $_POST['password'];
//include db connect
require_once __DIR__ . "/db_connect.php";
//connect to db
$db = new DB_CONNECT();
//mysql inserting a new row
$result = mysqli_query("INSERT INTO users(First_name, Surname, PhoneNo, Email, Password) VALUES('$fname', '$sname', '$phoneno','$email', '$password')");
//check if row is inserted
if($result){
$response['success'] = 1;
$response['message'] = "Successfully inserted";
//echoing JSON response
echo json_encode($response);
}else{
//failed to insert row
$response['success'] = 0;
$response['message'] = "An error occured.";
//echo JSON response
echo json_encode($response);
}
}else{
$response['success'] = 0;
$response['message'] = "required field(s) missing.";
//echo JSON response
echo json_encode($response);
}?>
db_connect
class DB_CONNECT {
//constructor
function __construct(){
//connecting to database
$this -> connect();
}
//destructor
function __destruct(){
//closing db connection
$this -> close();
}
/*
* Function to connect to database
*/
function connect(){
//import database connection variables
require_once __DIR__ . '/db_config.php';
//connecting to mysql database
$con = mysqli_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysqli_connect_error()) or die(mysqli_error());
//selecting database
$db = mysqli_select_db(DB_DATABASE) or die(mysqli_error());
//returning connection cursor
return $con;
}
function close(){
//closing db connection
mysqli_close();
}
}?>
db_config
define('DB_USER', "root"); //db user
define('DB_PASSWORD', ""); //db password
define('DB_DATABASE', "pom"); //database name
define('DB_SERVER', "localhost");
?>
以上是我尝试连接到数据库时应调用的所有代码。它应该在我的MySQL数据库中的users表中添加一个新条目,并且在应用程序上应该将我带到另一个屏幕,但是表中没有条目,并且该应用程序将引发超时错误。我的计算机的本地IP是192.168.0.18,而我的电话是192.168.0.55。我尝试使用端口80,未指定端口,但是现在尝试使用3000,但是所有这些都给出了超时错误。最后一件有用的事情是该请求甚至没有出现在apache日志中。我希望能看到与此类似的东西
192.168.0.55 - - [27/Jun/2019:11:30:01 +0100] "POST /pom/add_user.php HTTP/1.1" 200 52
但是最近一次我运行它时,访问日志或错误日志中都没有条目。
更新:
我决定检查Wireshk,以查看数据包是否通过。我得到了这张照片:
211 18.541329 192.168.0.55 192.168.0.18 TCP 74 38066 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=15216282 TSecr=0 WS=256
214 19.556572 192.168.0.55 192.168.0.18 TCP 74 [TCP Retransmission] 38066 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=15216383 TSecr=0 WS=256234
234 21.556683 192.168.0.55 192.168.0.18 TCP 74 [TCP Retransmission] 38066 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=15216583 TSecr=0 WS=256
287 25.554442 192.168.0.55 192.168.0.18 TCP 74 [TCP Retransmission] 38066 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=15216984 TSecr=0 WS=256
396 33.572515 192.168.0.55 192.168.0.18 TCP 74 [TCP Retransmission] 38066 → 80 [SYN] Seq=0 Win=65535 Len=0 MSS=1460 SACK_PERM=1 TSval=15217786 TSecr=0 WS=256
似乎握手失败。这是否意味着我的apache配置不正确?还是防火墙问题。我添加了例外,以允许我的计算机和路由器防火墙上的192.168.0.55至192.168.0.18通信。
更新2: 现在正在工作。握手以及http请求和200 OK。对于任何遭受相同问题困扰的人,这都是防火墙问题。对我来说,有3个防火墙:
我为所有规则制定了规则,以使流量通过。不幸的是,由于某些原因,windows仍然是Windows,但它仍被阻止。当我禁用Windows Defender时,所有数据包都通过了。即使我有一个针对防守者的入站规则,它仍然不喜欢它,因此可能需要牢记。