Android Studio 连接到 Socket 服务器
Posted
技术标签:
【中文标题】Android Studio 连接到 Socket 服务器【英文标题】:Android Studio Connect to Socket server 【发布时间】:2021-08-12 08:30:40 【问题描述】:我有一个使用 Eclipse 在 Java 中运行的服务器(这里是完整代码):
public class Main
public static void main(String[]args)
// BBDD connection var
Connection con = null;
// Sockets
ServerSocket server = null;
try
server = new ServerSocket(5010);
catch (IOException e2) System.out.println("Error at creating server, check if the port is in use");System.exit(-1);
/*** mysql driver loading***/
try
Class.forName("com.mysql.jdbc.Driver");
System.out.println("MySQL driver is UP");
catch (ClassNotFoundException e1) System.out.println("Error loading MySQL driver");
/*** Stablishing connection with the ddbb ***/
try
con= (Connection) DriverManager.getConnection("jdbc:mysql://IP/Database", "username", "password");
System.out.println("Connection stablished");
catch (SQLException e)
System.out.println("SQL ERROR");
e.printStackTrace();
/*** Assigning thread for client ***/
System.out.println("Listening for new requests...");
while (true)
try
Socket clientSocket;
clientSocket = server.accept();
System.out.println("Connection stablished");
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream());
ThreadForClient client = new ThreadForClient(con, clientSocket, dis, dos);
Thread thread = new Thread(cliente);
thread .start();
catch (IOException e) System.out.println("Error making client socket");
class ThreadForClient implements Runnable
Connection con;
Socket clientSocket;
DataInputStream dis;
DataOutputStream dos;
public ThreadForClient(Connection con, Socket s, DataInputStream dis, DataOutputStream dos)
this.con = con;
this.clientSocket = s;
this.dis = dis;
this.dos = dos;
@Override
public void run()
try
int opc = dis.readInt();
switch (opc)
case 1:
String email = dis.readUTF();
Boolean result = existeUsuario(email);
dos.writeBoolean(result);
break;
default: break;
catch (Exception e)
e.printStackTrace();
public Boolean userExists(String email) throws SQLException // 1
email = email.toLowerCase();
Statement stmt;
stmt = con.createStatement();
ResultSet rs=stmt.executeQuery("select * from users where email = '"+email+"'");
boolean result = rs.first();
return result;
如您所见,客户端发送 2 个值并接收 1 个,第一个用于切换,这将指示要执行的内容,现在我只有 on 选项(检查 ddbb 中是否存在电子邮件),第二个值是电子邮件,因为代码已经进入开关。
服务器完全正常工作,我已经在 Eclipse 中使用客户端测试项目对其进行了测试(这是我想在 android Studio 中做的):
public static void main(String[] args)
Socket socket = null;
try
socket = new Socket(HOST, PORT);
System.out.println("Conection succesful");
DataOutputStream dos;
DataInputStream dis;
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
dos.writeInt(1);
dos.writeUTF("email@example.com");
Boolean bool = dis.readBoolean();
if (bool)
System.out.println("Email exists in the BBDD.");
else
System.out.println("Email does not exist in the BBDD.");
socket.close();
catch (Exception e) System.out.println("Server connection failed");
现在我想做的是在 Android Studio 中执行相同的客户端,以便它可以连接到服务器。
我试过了:
public class SocketConnection
UserExists ue;
public SocketConnection() throws IOException
connect();
public void connect()
ue = new UserExists();
ue.execute();
class UserExists extends AsyncTask<Void, Void, Void>
int PORT = 5010;
String HOST = "192.168.1.5";
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
@Override
protected Void doInBackground(Void... voids)
try
socket = new Socket(HOST, PORT);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
catch (Exception e)
System.out.println("Socket error");
e.printStackTrace();
return null;
@Override
protected void onPostExecute(Void result)
super.onPostExecute(result);
当我运行它时,它不会给我任何错误,但是如果我在 doInBackground 底部记录套接字值以查看套接字值,它会说它是空的。
我也尝试过使用 Thread 和 Handle,但我无法得到服务器返回给我的主线程的结果。
【问题讨论】:
【参考方案1】:根据 RFC 1918,192.168.0.0-192.168.255.255 范围内的地址是私有的。此类地址可以在任何网络内部使用,因此它们经常在组织内部使用。它们不能在 Internet 上使用,因为它们不是唯一的。 Why my ip address starts with 192.?
我认为您的本地网络以某种方式阻止了该连接。但没有进一步的细节,据我所知,没有人能真正说出。
如果您在同一台计算机上运行所有内容,您可能需要查看“环回”地址。通常是 127.0.0.1 ,应该循环回你的机器。
如果您想运行完整的服务器,您可能需要更深入地研究网络并想了解网络的运作方式。
【讨论】:
我现在刚刚尝试使用我的公共 IP 打开端口并将 AsyncTask 主机方向更改为:83.**.**.**:5010 但它不起作用,它没有执行该方法仍然将套接字服务器保留为空。 你从哪里得到 83.xx.xx.xx:5010? 这是我的公网IP,所以我把它换成了'x'。 现在它可以工作了,我尝试使用我的本地 IP 地址 (192.168.1.5) 并且也可以工作!这不是知识产权问题。您可以使用 192.x.x.x、127.0.0.1 (localhost) 和公共地址。您可以在whatismyipaddress.com 找到您的,只是不要忘记在您的路由器中打开正确的端口!【参考方案2】:我设法解决了这个问题。我刚刚在 Android Studio 的“连接”类中创建了一个线程。
在“连接”中,我有一些类级变量,我与线程一起使用(线程无法修改创建线程的方法中的变量,但它可以读取类级变量)所以线程本身使与套接字服务器的连接,并将取值保存到类级变量中。
在主线程中(在调用线程的同一方法中)我使用了一个循环来查看线程状态,如果它已完成,则读取变量并将其应用到我想要的位置。
代码如下:
public class Connection
private String HOST = "83.xx.xx.xx";
private int PORT = 5010;
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
boolean result;
String email;
public boolean userExists(String dev) throws InterruptedException // true = exists, false = does not exist. dev is the email to search
this.email = dev;
Thread thread = new Thread(new Runnable()
@Override
public void run()
try
socket = new Socket(HOST, PORT);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream((socket.getInputStream()));
dos.writeInt(1); // 1 = Sends the option for telling the server that we want to search a user
dos.writeUTF(email); //Sends the email
result = dis.readBoolean(); // Recieve if email exists or not
socket.close();
catch (IOException e)
e.printStackTrace();
System.out.println("Couldn't connect to server");
);
thread.start();
for (int c=0; c<25; c++) //Wait for the thread to end
if (thread.isAlive())
//Thread hasn't finished yet...
Thread.sleep(100);
else if (c == 24)
//This would be a timeout
result = false;
else
//Thread has finished
break;
return result; // true in case server found the email, false in case it doesn't or in case of a timeout
我认为另一种可能性是让线程只进行连接(以及另一个用于关闭它)并将套接字保存为类级变量,这样您就可以从主线程发送和接收,我没有尝试还是这样。
【讨论】:
以上是关于Android Studio 连接到 Socket 服务器的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Android 手机连接到 Visual Studio Code?
从 Android Studio 连接到 SQL Server 2014
最近的 Android Studio 无法连接到 Firebase?