我正在尝试创建一个客户端/服务器应用程序,其中,笔记本电脑就像服务器一样,与一个像客户端一样的Android手机共享其互联网连接,我可以 Build 客户端和服务器之间的连接,问题是当客户端尝试时在套接字上写,它会卡在那里 . 这是android xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.giuseppe.client">
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
这是android客户端
package com.example.giuseppe.client;
import java.io.*;
import java.net.*;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import org.w3c.dom.Text;
import static java.net.InetAddress.*;
public class MainActivity extends Activity {
private Socket socket;
private static final int port=5555;
private static final String addr="192.168.1.37";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Client()).start();
}
public void onClick(View view){
try{
TextView tx=(TextView) findViewById(R.id.txt);
EditText et= (EditText) findViewById(R.id.et);
String str= et.getText().toString();
DataOutputStream out= new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())) ;
out.writeUTF(str);
out.close();
socket.close();
}catch(UnknownHostException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
class Client implements Runnable {
@Override
public void run() {
try {
TextView tx= (TextView) findViewById(R.id.txt);
tx.setText("Before connection");
InetAddress server = InetAddress.getByName(addr);
socket = new Socket("192.168.1.37", port);
tx.setText("After connection");
} catch (UnknownHostException a) {
} catch (IOException a) {
} catch (Exception a){
}
}
}
这是服务器代码
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
int port=5555;
byte[] buff =new byte[1024];
String str;
// TODO Auto-generated method stub
try {
ServerSocket server=new ServerSocket(port);
System.out.println("Before accept");
Socket client=server.accept();
System.out.println("After accept");
DataInputStream in=new DataInputStream(new BufferedInputStream(client.getInputStream()));
str=in.readUTF();
System.out.println("Message received");
in.close();
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我想问题是在客户端,因为我也试图使用服务器发送一个字符串,当服务器发送它时,客户端没有收到它 . 对不起,我的英语不好 . 谢谢大家
编辑
我也试过OutputStream out = socket.getOutputStream();然后out.write(str.getBytes()),但是在这种情况下它会卡在这里,当我尝试在套接字中写入时,可能是任何android的配置问题?
2 回答
免责声明:我无法验证您的Android代码的正确性,所以我假设这很好,只评论您的网络代码,这是您的问题的根本原因 .
您的代码中的2个主要问题是:
在您的服务器代码中,您正在阅读和阅读,什么都不做
您的服务器是单线程的
你的主要问题是上面的#1,一旦你解决了你的#1,你将会遇到另一个问题#2 .
Your #1 problem 是你需要定义一些关于如何考虑流结束或输入的逻辑,参考下面的代码示例( read the comments in the code ),你也不一定需要使用
readUTF
方法,而是可以使用“ I/O bridge classes ”之类的InputStreamReader
充当 byte stream 和 character stream 之间的桥梁,所以你可以使用InputStreamReader clientSocketReader = (new InputStreamReader(clientSocket.getInputStream(), "UTF8"));
,我不能说为什么你真的需要DataInputStream
并且不能使用InputStreamReader
但是在我看来你可以去使用桥类 .Now your #2 problem 是您的服务器是单线程的,您需要有一个多线程服务器,这基本上意味着您应该在新线程中处理每个客户端请求 . 阅读我的this answer,这会在单线程v / s多线程服务器上引发更多亮点 . 请参阅以下多线程服务器的代码示例:
那是一个艺术问题 . 服务器从接受返回后,客户端已 Build 与服务器的连接 . 当Sever正在等待数据读取(消费者)时,客户端( 生产环境 者)什么都不做 . 客户端 should write something on The Socket 为了继续 .