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

工具的准备:

编写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;

/**
 * 

* Socket线程服务类 *

* */ 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;
/**
 * 

* 基于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) {

    }
}

 

 

 

 

 

最后就是运行效果了:

第一步:启动服务端

使用Socket进行一台服务器与多个Android客户端进行双向通信_第1张图片

 

 

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

使用Socket进行一台服务器与多个Android客户端进行双向通信_第2张图片使用Socket进行一台服务器与多个Android客户端进行双向通信_第3张图片

 

服务台的打印台输出:

使用Socket进行一台服务器与多个Android客户端进行双向通信_第4张图片

 

再用真机发送一句中文:

使用Socket进行一台服务器与多个Android客户端进行双向通信_第5张图片

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

 

 

 

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

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

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

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

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

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

使用Socket进行一台服务器与多个Android客户端进行双向通信_第6张图片

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

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

使用Socket进行一台服务器与多个Android客户端进行双向通信_第7张图片

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

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

使用Socket进行一台服务器与多个Android客户端进行双向通信_第8张图片

第四步:编写代码

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

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

 

 

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

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

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

使用Socket进行一台服务器与多个Android客户端进行双向通信_第9张图片

 

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

http://www.cnblogs.com/forget406/p/5336748.html

http://www.cnblogs.com/parryyang/p/6282563.html

你可能感兴趣的:(android笔记,服务器)