天天看点

WIfi Socket数据传输

在同一个局域网中我们是可以利用Socket进行通信的,所以当两台手机通过wifi连接的时候,并可以通过socket进行通信了。

使用过Socket,我们都知道进行socket通信需要一个服务端和客户端。所以,如果你需要实现茄子快传的文件传输功能,你就可以将你发送文件的手机做服务端,接收文件的手机作客户端。

下面模拟客户端和服务端对话的功能,即客户端发送消息服务端能够接收并且显示,服务端发送消息客户端可以接收并显示。为了简单:发送消息的功能就是直接将EditText的内容发送给服务端(客服端),而显示则是在while循环客户端(服务端)发送来的信息实时获取并显示。

具体实现如下:

  • 服务端:
//开启一个子线程去处理
     new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    serverSocket = new ServerSocket();
                    while (true) {
                        socket = serverSocket.accept();
                        Log.d("test", "有客户端连接上。。。");
                        OutputStream ou = socket.getOutputStream();
                        //向服务器发送信息
                        ou.write((etInput.getText().toString().trim() + "\n").getBytes("gbk"));

                        InputStream is = socket.getInputStream();
                        //千万不要使用readLine()方法去读取
                        byte[] b = new byte[];
                        int x = is.read(b, , b.length);
                        String line = new String(b, , x);
                        if (x > ) {
                            line = new String(b, , x);
                        }
                        final String str = line;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tvClientMsg.setText(str);
                            }
                        });
                        is.close();
                        ou.flush();
                        ou.close();
                        socket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
           
  • 客户端:

    与服务端类似

new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        //连接服务器 并设置连接超时为1秒
                        socket = new Socket();          
                        socket.connect(new InetSocketAddress(IP, ), ); //端口号为30000               
                        OutputStream ou = socket.getOutputStream();
                        //向服务器发送信息
          ou.write((evInput.getText().toString().trim() + "\n").getBytes("gbk"));
                        Log.d("test", "####2###");
                        InputStream is = socket.getInputStream();
                        byte[] b = new byte[];
                        int x = is.read(b, , b.length);
                        String line ="";
                        if(x>) {
                            line = new String(b, , x);
                        }
                        final String str =line;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tvServerMsg.setText(str);
                            }
                        });
                        //关闭各种输入输出流
                        is.close();
                        ou.flush();
                        ou.close();
                        socket.close();
                    } catch (SocketTimeoutException aa) {           
                        Log.d("test", "连接超时");
                        Log.d("test", aa.getMessage());
                        aa.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
           

获取Ip的方法:

WifiManager wifiManager = (WifiManager)  getApplicationContext().getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcpinfo = wifiManager.getDhcpInfo();
//调用转换方法intToIp
final String IP = intToIp(dhcpinfo.serverAddress);

/**
** 返回IP地址
*/
private String intToIp(int paramInt) {
        return (paramInt & ) + "." + ( & paramInt >> ) + "." + ( & paramInt >> ) + "."
                + ( & paramInt >> );
    }
           

需要注意的事:

在读取消息的时候,请不要使用readLine方法(),因为这个方法会阻塞,此时你的程序会阻塞在此,然后就会出现无法正常显示接收到的数据。因为,一旦readLine()方法没有数据读取的时候就会阻塞在那里,程序没法往下走,而其他的read方法则会返回-1.

可以参考: 被readLine()折腾了一把

下一篇:wifi状态下实现文件传输