Android 客户端Socket 与 Java服务端ServerSocket 简单小例子

时间:2022-11-30 18:04:12

新建一个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地址对不上的问题,这需要自行百度

注:代码写的并不规范!!!