zoukankan      html  css  js  c++  java
  • Android客户端与PC服务端、android服务端通过WiFi通信

    前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端,通过socket进行通信。

    1.在eclipse下写好服务器端的代码,包括监听的端口好,客户端的IP地址获取,发送的数据处理等,这里涉及到J2EE的环境配置,有时间我在写下,这个代码是直接百度到的,能用:

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Test {
        private ServerSocket server;
        private Socket client;
        private BufferedReader in;
        private PrintWriter out;
    
        public Test() {
            try {
                server = new ServerSocket(9400);
                while (true) {
                    System.out.println("start!");
                    // 获得客户端连接
                    client = server.accept();
                    // 获得客户端的IP和端口
                    String remoteIP = client.getInetAddress().getHostAddress();
                    int remotePort = client.getLocalPort();
    
                    System.out.println("A client connected. IP:" + remoteIP
                            + ", Port: " + remotePort);
                    System.out.println();
    
                    // 获得 client 端的输入输出流,为进行交互做准备
                    in = new BufferedReader(new InputStreamReader(
                            client.getInputStream()));
                    out = new PrintWriter(client.getOutputStream(), false);
    
                    // 获得 client 端发送的数据
                    String tmp = in.readLine();
                    // String content = new String(tmp.getBytes("utf-8"));
                    System.out.println("Client message is: " + tmp);
    
                    // 向 client 端发送响应数据
                    out.println("Your message has been received successfully!.");
    
                    // 关闭各个流
                    out.close();
                    in.close();
                    // server.close();
                }
            } catch (Exception e) {
                // 发送响应,接收失败
                System.out.println(e.toString());
                out.println("Receive Error!");
            }
        }
    
        public static void main(String[] args) {
            new Test();
        }
    
    }

    代码看起来也不是太难,关键是Java EE的使用,尤其是服务器的配置,(配置教程涉及到tomcat的配置,以及服务器的建立),

    Project name随便写好了,然后next---->next,需要把Generate web.xml deployment descriptor勾选上。注意:

    Java Resources 下的src文件夹下里面放的是相关的类,这个类写完之后还在Webcontent文件夹--->WEB-INF文件夹下的web.xml里面配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">
        <display-name>TomcatTest</display-name>
        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
        <servlet>
            <servlet-name>Test</servlet-name>
            <servlet-class>Test</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>Test</servlet-name>
            <url-pattern></url-pattern>
        </servlet-mapping>
    </web-app>
    View Code

    到这里你可以运行你的服务端,选中项目,右击选中Run as--->Run on server,到此你的网站基本上就发布成功了,在你的手机的浏览器中输入你PC端的IP地址,注意端口号是9400,比如我之前测试的用是的10.3.19.26:9400,就可以看到服务端返回的信息。

    2.android端的程序比较简单,但是一开始的时候怎么都不能成功运行,最后发现的两个问题a.权限没有加,b.自从android3.0以后,android的运行机制不容许在主线程中使用网络的相关操作

    我的值加了这几个权限,貌似也能够运行起来,呵呵:

        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    第二个问题,网上的一些代码太坑了,明明都是有问题,也不知道修改,下面写的很简单,没有图形界面,

    package com.example.client;
    
    import java.io.IOException;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
        private Button btnConnect, btnSend;
        private Socket socket;
        private PrintStream output;
        private EditText editSend;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btnConnect = (Button) findViewById(R.id.button1);
            btnSend = (Button) findViewById(R.id.button2);
            editSend = (EditText) findViewById(R.id.editText1);
            btnConnect.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    new Thread(runnable).start();//开启线程
                }
            });
            btnSend.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    sendMessage(editSend.getText().toString());
    
                }
            });
    
        }
        Runnable runnable = new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                initClientSocket();
            }
        };
    
        public void initClientSocket() {
            try {
                EditText edit_ip = (EditText) MainActivity.this.findViewById(R.id.editText2);
                String ip = edit_ip.getText().toString().trim();
                socket = new Socket("10.3.19.26", 9400);
                output = new PrintStream(socket.getOutputStream(), true, "gbk");
    
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                Toast.makeText(MainActivity.this, "请检查端口号是否为服务器IP",
                        Toast.LENGTH_LONG).show();
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Toast.makeText(MainActivity.this, "服务器未开启", Toast.LENGTH_LONG)
                        .show();
                e.printStackTrace();
            }
            output.println("this is the message from client");
        }
    
        private void sendMessage(String str) {
            output.println(str);
        }
    
        public void closeSocket() {
            try {
                output.close();
                socket.close();
            } catch (IOException e) {
                System.out.println("error"+e);
            }
        }
    
    }

    基本上控件只有一个按钮,其他的都是没有用的,在按钮的监听器里面写的方法,就是使用Runable开启一个线程,在runable的方法中调用initClientSocket()方法,你会发现,里连接的代码很简单,我连接成功后就使用

    output.println("this is the message from client");

    这个就是返回给服务器的信息,一开始放在另一个按钮中的,但是考虑到上述的问题,还是直接在线程中发送(我测试过,在UI线程中不能使用这个方法,发送完了也没有反应)最终的服务器端接受的数据情况如下:

    从下午到晚上总算弄完了2015-05-18 22:11:21,有时间把相关的配置弄下。

    2015年5月19日星期二 21:53在github上看到一个程序,用的是内部异步任务方法处理的,放在这里参考下,很简单就是一个MainActivity.java:

      1     package com.example.androidclient;
      2 
      3     import java.io.ByteArrayOutputStream;
      4     import java.io.IOException;
      5     import java.io.InputStream;
      6     import java.net.Socket;
      7     import java.net.UnknownHostException;
      8 
      9     import android.os.AsyncTask;
     10     import android.os.Bundle;
     11     import android.app.Activity;
     12     import android.view.View;
     13     import android.view.View.OnClickListener;
     14     import android.widget.Button;
     15     import android.widget.EditText;
     16     import android.widget.TextView;
     17 
     18     public class MainActivity extends Activity {
     19         
     20         TextView textResponse;
     21         EditText editTextAddress, editTextPort;//用户自己输入的服务器端的地址和端口号 
     22         Button buttonConnect, buttonClear;
     23 
     24         @Override
     25         protected void onCreate(Bundle savedInstanceState) {
     26             super.onCreate(savedInstanceState);
     27             setContentView(R.layout.activity_main);
     28             
     29             editTextAddress = (EditText)findViewById(R.id.address);
     30             editTextPort = (EditText)findViewById(R.id.port);
     31             buttonConnect = (Button)findViewById(R.id.connect);
     32             buttonClear = (Button)findViewById(R.id.clear);
     33             textResponse = (TextView)findViewById(R.id.response);
     34             
     35             buttonConnect.setOnClickListener(buttonConnectOnClickListener);
     36             
     37             buttonClear.setOnClickListener(new OnClickListener(){
     38 
     39                 @Override
     40                 public void onClick(View v) {
     41                     textResponse.setText("");
     42                 }});
     43         }
     44         
     45         OnClickListener buttonConnectOnClickListener = 
     46                 new OnClickListener(){//连接的监听器
     47 
     48                     @Override
     49                     public void onClick(View arg0) {
     50                         MyClientTask myClientTask = new MyClientTask(
     51                                 editTextAddress.getText().toString(),
     52                                 Integer.parseInt(editTextPort.getText().toString()));//构造异步任务内部类
     53                         myClientTask.execute();
     54                     }};
     55 
     56         public class MyClientTask extends AsyncTask<Void, Void, Void> {//异步任务
     57             
     58             String dstAddress;
     59             int dstPort;
     60             String response = "";
     61             
     62             MyClientTask(String addr, int port){//构造方法,传进IP地址和对应的端口号
     63                 dstAddress = addr;
     64                 dstPort = port;
     65             }
     66 
     67             @Override
     68             protected Void doInBackground(Void... arg0) {
     69                 
     70                 Socket socket = null;//
     71                 
     72                 try {
     73                     socket = new Socket(dstAddress, dstPort);//建立连接,需要try-catch
     74                     
     75                     ByteArrayOutputStream byteArrayOutputStream = 
     76                             new ByteArrayOutputStream(1024);
     77                     byte[] buffer = new byte[1024];
     78                     
     79                     int bytesRead;
     80                     InputStream inputStream = socket.getInputStream();
     81                     
     82                     /*
     83                      * notice:
     84                      * inputStream.read() will block if no data return
     85                      */
     86                     while ((bytesRead = inputStream.read(buffer)) != -1){
     87                         byteArrayOutputStream.write(buffer, 0, bytesRead);
     88                         response += byteArrayOutputStream.toString("UTF-8");
     89                     }
     90 
     91                 } catch (UnknownHostException e) {
     92                     // TODO Auto-generated catch block
     93                     e.printStackTrace();
     94                     response = "UnknownHostException: " + e.toString();
     95                 } catch (IOException e) {
     96                     // TODO Auto-generated catch block
     97                     e.printStackTrace();
     98                     response = "IOException: " + e.toString();
     99                 }finally{
    100                     if(socket != null){
    101                         try {
    102                             socket.close();
    103                         } catch (IOException e) {
    104                             // TODO Auto-generated catch block
    105                             e.printStackTrace();
    106                         }
    107                     }
    108                 }
    109                 return null;
    110             }
    111 
    112             @Override
    113             protected void onPostExecute(Void result) {//更新UI线程
    114                 textResponse.setText(response);
    115                 super.onPostExecute(result);
    116             }
    117             
    118         }
    119 
    120     }
    View Code

    那么对应的服务器android端的代码如下,写的也很简单浅显易懂:MainActivity.java

    package com.example.androidserversocket;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintStream;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketException;
    import java.util.Enumeration;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
    
        TextView info, infoip, msg;
        String message = "";
        ServerSocket serverSocket;//ServerSocket实例
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            info = (TextView) findViewById(R.id.info);
            infoip = (TextView) findViewById(R.id.infoip);
            msg = (TextView) findViewById(R.id.msg);
            
            infoip.setText(getIpAddress());//
    
            Thread socketServerThread = new Thread(new SocketServerThread());
            socketServerThread.start();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
    
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
        private class SocketServerThread extends Thread {
    
            static final int SocketServerPORT = 8080;
            int count = 0;
    
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket(SocketServerPORT);//监听端口
                    MainActivity.this.runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            info.setText("I'm waiting here: "
                                    + serverSocket.getLocalPort());
                        }
                    });
    
                    while (true) {//接受客户端的信息
                        Socket socket = serverSocket.accept();
                        count++;
                        message += "#" + count + " from " + socket.getInetAddress()
                                + ":" + socket.getPort() + "
    ";
    
                        MainActivity.this.runOnUiThread(new Runnable() {
    
                            @Override
                            public void run() {
                                msg.setText(message);
                            }
                        });
    
                        SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
                                socket, count);
                        socketServerReplyThread.run();
    
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    
        private class SocketServerReplyThread extends Thread {
    
            private Socket hostThreadSocket;
            int cnt;
    
            SocketServerReplyThread(Socket socket, int c) {
                hostThreadSocket = socket;
                cnt = c;
            }
    
            @Override
            public void run() {
                OutputStream outputStream;
                String msgReply = "Hello from Android, you are #" + cnt;
    
                try {
                    outputStream = hostThreadSocket.getOutputStream();
                    PrintStream printStream = new PrintStream(outputStream);
                    printStream.print(msgReply);
                    printStream.close();
    
                    message += "replayed: " + msgReply + "
    ";
    
                    MainActivity.this.runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            msg.setText(message);
                        }
                    });
    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    message += "Something wrong! " + e.toString() + "
    ";
                }
    
                MainActivity.this.runOnUiThread(new Runnable() {
    
                    @Override
                    public void run() {
                        msg.setText(message);
                    }
                });
            }
    
        }
    
        private String getIpAddress() {
            String ip = "";
            try {
                Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                        .getNetworkInterfaces();
                while (enumNetworkInterfaces.hasMoreElements()) {
                    NetworkInterface networkInterface = enumNetworkInterfaces
                            .nextElement();
                    Enumeration<InetAddress> enumInetAddress = networkInterface
                            .getInetAddresses();
                    while (enumInetAddress.hasMoreElements()) {
                        InetAddress inetAddress = enumInetAddress.nextElement();
    
                        if (inetAddress.isSiteLocalAddress()) {
                            ip += "SiteLocalAddress: " 
                                    + inetAddress.getHostAddress() + "
    ";
                        }
                        
                    }
    
                }
    
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                ip += "Something Wrong! " + e.toString() + "
    ";
            }
    
            return ip;
        }
    }
    View Code
  • 相关阅读:
    input File 提交文件上传 无法传递数据的原因
    谈谈运维该掌握那些技能
    虚拟机vmware 下Centos 系统磁盘扩容
    jenkins针对不同的项目组对用户进行权限分配
    Mac Catalina 手残误删系统文件恢复过程
    自动化持续集成
    zabbix 监控之主动配置模式
    nginx对请求后缀或IP访问限制
    elasticsearch7.2.1 报错 Received fatal alert: handshake_failure
    使用nexus创建npm私服
  • 原文地址:https://www.cnblogs.com/sowhat4999/p/4513204.html
Copyright © 2011-2022 走看看