新建一个Java项目
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Server { private final int SERVERPORT = 9898;//定义端口 private ServerSocket serverSocket; //声明服务器套接字 private OutputStream outputStream; //声明输出流 private InputStream inputStream; //声明输入流 private PrintWriter printWriter; //声明打印流 private Socket socket; //声明套接字 private BufferedReader reader; //声明缓冲流,用于读取接收的数据 public Server(){ try { //根据指定端口号,创建套接字 serverSocket = new ServerSocket(SERVERPORT); System.out.println("服务启动..."); socket = serverSocket.accept();//用accept()方法等待客户端的连接 System.out.println("客户端已连接..."); } catch (IOException e) { e.printStackTrace(); } try { outputStream = socket.getOutputStream();//获取套接字输出流 inputStream = socket.getInputStream(); //获取套接字输入流 //根据输出流创建PrintWriter对象(用于写入数据) printWriter = new PrintWriter(outputStream,true); //根据输入流创建BufferedReader对象(用于读取数据) reader = new BufferedReader(new InputStreamReader(inputStream)); /* * 根据System.in创建BufferedReader对象 * BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); * 拆开为: * InputStream is = System.in; //(System.in)接受从控制台输入的字节 * InputStreamReader isr = new InputStreamReader(in); //将字节流转换为字符流 * BufferedReader br = new BufferedReader(isr); //将字符流存入缓冲流 */ BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while(true){ String message = reader.readLine(); //读取客户端传输的信息 System.out.println("来自客户端的信息:" + message); //将接收的信息输出 if(message.equals("Bye")||message.equals("bye")) //如果信息为“Bye”或“bye”,则结束通信 break; message = in.readLine(); //接受键盘输入 printWriter.println(message); //将接受的信息向客户端输出 } outputStream.close(); inputStream.close(); socket.close(); serverSocket.close(); System.out.println("客户端关闭连接..."); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new Server(); } }
新建一个Android项目:
其中Activity:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.app.Activity; public class ClientActivity extends Activity implements Runnable,OnClickListener{ private TextView chatmessage; //用于显示聊天记录 private EditText sendmessage; //用于用户输入短信内容 private Button send_btn; //用于发送短信 private static final String HOST = "10.0.2.2";//服务器IP地址 private static final int PORT = 9898; //服务器端口号 private Socket socket; private BufferedReader reader; private PrintWriter writer; private String str = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_client); chatmessage = (TextView) this.findViewById(R.id.chatmessage); sendmessage = (EditText) this.findViewById(R.id.sendmessage); send_btn = (Button) this.findViewById(R.id.send_btn); send_btn.setOnClickListener(this); new Thread(this).start();//启动线程 } @Override public void run() { /* * state>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * * 这一坨代码本来是直接写在onCreate()中,但运行时报了android.os.NetworkOnMainThreadException错误, * 后来根据园友的:https://www.cnblogs.com/lixiaolun/p/3472757.html 解决 */ try { //指定ip和端口号,创建套接字 socket = new Socket(HOST,PORT); //使用套接字的输入流构造BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //使用套接字的输出流构造PrintWriter OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream()); BufferedWriter bw = new BufferedWriter(osw); writer = new PrintWriter(bw,true); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //end>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> try { while(true){ //若套接字连接服务器,且输入流没有关闭 if(socket.isConnected()){ if(!socket.isInputShutdown()){ if((str = reader.readLine())!= null){ str += " "; handler.sendMessage(handler.obtainMessage()); } } } } } catch (IOException e) { e.printStackTrace(); } } @Override public void onClick(View arg0) { if(arg0.getId() == R.id.send_btn){ //获取输入框内容 String message = sendmessage.getText().toString().trim(); //判断socket是否连接 if(socket.isConnected()){ //如果输出关闭,则不执行 if(socket.isOutputShutdown()) return; writer.println(message);//将输出内容发送到服务器 //设置chatmessage内容 chatmessage.setText(chatmessage.getText()+"\n"+"发送:"+message); //清空sendmessage的内容,以便下次输入 sendmessage.setText(""); } } } public Handler handler = new Handler(){ public void handleMessage(Message msg){ super.handleMessage(msg); chatmessage.setText(chatmessage.getText().toString()+"\n"+"来自服务器端的消息:" + str); } }; }
对应的 xml 布局文件(activity_client.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ClientActivity" > <TextView android:id="@+id/chatmessage" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:hint="聊天记录。。。" /> <EditText android:id="@+id/sendmessage" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:hint="请输入..." /> <Button android:id="@+id/send_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送" /> </LinearLayout>
还有AndroidManifest.xml 中记得申请权限:
<uses-permission android:name="android.permission.INTERNET"/><!-- 访问网络权限 -->
最后,先启动Java项目,然后在启动Android项目
注:如果运行报错,多半是IP地址对不上的问题,这需要自行百度
注:代码写的并不规范!!!