Android 客戶端Socket 與 Java服務端ServerSocket 簡單小例子


新建一個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地址對不上的問題,這需要自行百度

注:代碼寫的並不規范!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM