使用Socket进行一台服务器与多个Android客户端进行双向通信

来源:互联网 发布:政务大数据市场分析 编辑:程序博客网 时间:2024/05/16 15:51

工具的准备:

编写Web服务端的代码:IDEA

编写Android客户端的代码: Android Studio

web服务端的部署工具:Tomcat 7.0.82



代码清单:

客户端:

package com.example.administrator.filetransportapp;import android.app.Activity;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.TextView;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.util.Scanner;public class MainActivity extends Activity {    String IP="175.0.152.169";    int PORT=8000;    EditText et_message;    TextView tv_result;    StringBuffer stringBuffer=new StringBuffer();    String message;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Init();    }    public void Init(){        et_message= (EditText) findViewById(R.id.message);        tv_result= (TextView) findViewById(R.id.tv_result);    }    public void SendMessage(View v){        Send();    }    public void Send(){        Thread th=new Thread(new Runnable() {            @Override            public void run() {                try {                    Socket socket=new Socket(IP,PORT);                    if(socket.isConnected()){                        System.out.println("连接主机成功");                    }else{                        System.out.println("连接主机失败");                    }                    OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");                         /* 客户端向服务器发送数据  */                    PrintWriter pw                            = new PrintWriter(osw, true);                    pw.println(et_message.getText().toString());                         /* 客户端接收服务器数据  */                    InputStreamReader isr = new InputStreamReader(socket.getInputStream(), "UTF-8");                    BufferedReader br = new BufferedReader(isr);                    String msgReceive = null;                    while(true) {                        if((msgReceive = br.readLine()) != null) {                            stringBuffer.append(msgReceive);                            runOnUiThread(new Runnable() {                                @Override                                public void run() {                                    tv_result.setText("\n"+stringBuffer.toString());                                }                            });                            System.out.println("服务器说:" + msgReceive);                        }                    }                } catch (IOException e) {                    System.out.println("\nSocket的连接失败");                    e.printStackTrace();                }            }        });        th.start();    }}


服务端代码清单【一共三个文件】:

1.ServerSocketThread类:

import java.io.*;import java.net.Socket;/** * <p> * Socket线程服务类 * <p> * */public class ServerSocketThread extends Thread {    private Socket socket;    public ServerSocketThread(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        InputStream is = null;        InputStreamReader isr = null;        BufferedReader br = null;        OutputStream os = null;        PrintWriter pw = null;        try {            // socket获取字节输入流            is = socket.getInputStream();            // 将字节输入流转字符输入流            isr = new InputStreamReader(socket.getInputStream(), "UTF-8");            // 将字符输入流转行输入流            br = new BufferedReader(isr);            String message = null;           if ((message = br.readLine()) != null) {                System.out.println("客户端发来消息:" + message+socket.getRemoteSocketAddress());            }            // 必须先关闭输入流才能获取下面的输出流            socket.shutdownInput();            String msgSend    = "\nhello I am server, I have receive your message: "+message;            /* 服务器向客户端发送数据  */            OutputStreamWriter osw = null;            osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");            pw = new PrintWriter(osw, true);            pw.println(msgSend);            pw.flush();            System.out.println("向客户端发送"+msgSend);        } catch (Exception e) {            e.printStackTrace();        } finally {            // 关闭输入流            try {                socket.shutdownOutput();            } catch (IOException e) {                e.printStackTrace();            }            // 收工前最后一步:关闭资源            try {                if (pw != null) {                    pw.close();                }                if (br != null) {                    br.close();                }                if (isr != null) {                    isr.close();                }                if (os != null) {                    os.close();                }                if (br != null) {                    br.close();                }                if (isr != null) {                    isr.close();                }                if (is != null) {                    is.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

2.Server类:

import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/** * <p> * 基于socket通讯-服务端 */public class Server {    private static ServerSocket SERVER_SOCKET =null;;    static{        try {            SERVER_SOCKET = new ServerSocket(8000);        } catch (IOException e) {            System.out.println("\n端口已被占用");            e.printStackTrace();        }    }    public void start(){     try {            System.out.println("-----服务器已启动,等待客户端连接----");            Socket socket = null;             while(true){                //循环监听客户端的连接                socket = SERVER_SOCKET.accept();                //新建一个线程ServerSocket,并开启                new ServerSocketThread(socket).start();             }         } catch (IOException e) {            e.printStackTrace();            }}    public static void main(String[] args) {        try {            System.out.println("-------服务器已启动,等待客户端连接----");            Socket socket = null;            while(true){                //循环监听客户端的连接                socket = SERVER_SOCKET.accept();                //新建一个线程ServerSocket,并开启                new ServerSocketThread(socket).start();            }        } catch (IOException e) {            e.printStackTrace();        }    }}


3.ServerListener

import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;public class ServerListener implements ServletContextListener {    @Override    public void contextInitialized(ServletContextEvent servletContextEvent) {        Thread thread=new Thread(new Runnable() {            @Override            public void run() {                Server server=new Server();                server.start();            }        });        thread.start();    }    @Override    public void contextDestroyed(ServletContextEvent servletContextEvent) {    }}


最后就是运行效果了:

第一步:启动服务端




第二步:打开Android虚拟机,发送消息



服务台的打印台输出:



再用真机发送一句中文:


[虚拟机那边,手抖,多按了一次发送,所以是发送了两次good job]




好的,现在,代码和效果已经展示完毕。

接下来记录一下我在编写代码时遇见过的问题以及解决方法:

问题一:做内网测试时,我的服务器所在的台式电脑与我的真机不在同一个内网,测试失败,怎么办?

解决方法一:用虚拟机做测试,因为电脑的虚拟机和台式电脑肯定是在同一个内网。

解决方法二:用外网映射,具体操作看下图:

第一步:查询本机的IP,win+R,打开cmd,输入:ipconfig查询到我的本机IP是:192.168.1.102

第二步:设置外网映射,打开浏览器,在地址栏输入:192.168.1.1 然后账号密码都是:admin

在网页的左侧,点击转发规则,在后面添加一个IP和Port:


第3步:查看电脑主机的外网IP地址

点击网页左侧的运行状态:


第四步:编写代码

服务端的Socket监听端口,将端口改为映射的端口,我的是8000.

在客户端Socket连接的IP改为服务器外网的IP,端口设置为8000,与上面的保持一致。



问题二:如何给web服务器添加监听?

这个问题,对各位读者可能没有普遍的借鉴意义,我就当是做个总结啦。

首先,要写好Socket的Server,其次是编写一个继承了ServerletContextListener的类,并在web.xml进行注册:


最重要的,差点忘记了,感谢以下两位博主的分享,让我可以学习,非常感谢~附上链接

阅读全文
0 0
原创粉丝点击