新建一個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地址對不上的問題,這需要自行百度
注:代碼寫的並不規范!!!