Socket实现两台手机通信,定向转发数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_23086307/article/details/51534059

最近要面试了,想练习一下网络编程吧,想想来搞搞实现太手机聊天功能吧,其实聊天功能有集成好的框架,有apache的mina框架,想要知道这个框架怎么用,看我的下一篇博客吧,现在我们开讲讲怎么用socket通信吧
首先,什么叫socket?字面意思叫 插座; 灯座; 窝,穴; [解] 眼窝,孔窝
网络用语叫套接字原理是基于tcp/ip 协议的一种通信手段,
下面来看我的客户端程序吧,首先新建一个java工程。里面就有一个类用于客户端提供服务;

package javagreendao;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SocketTest {
    private static List<Socket>listsocket=new LinkedList<Socket>();
    private static Map<String,Socket>mapsocket=new LinkedHashMap<>();
    public static void main(String[] args) {
        System.out.println("连接成功");
        int port=1001;
        try {
            @SuppressWarnings("resource")
            ServerSocket serverSocket=new ServerSocket(port);
            while (true) {
                //
                System.out.println("阻塞开始");
                final Socket socket=serverSocket.accept();
                listsocket.add(socket);
                ExecutorService executorService=Executors.newFixedThreadPool(listsocket.size());
                executorService.execute(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            //输入流获取客户端数据
                            InputStream inputStream=socket.getInputStream();
                            //输出流给客户端发数据
                            OutputStream outputStream=socket.getOutputStream();
                            byte[] buffer=new byte[1024];
                            int len;
                            while((len=inputStream.read(buffer))!=-1){
                                String text=new String(buffer, 0, len);
                                System.out.println("内容"+text);
                                if (text.startsWith("#")) {
                                    mapsocket.put(text, socket);
                                    outputStream.write("收到".getBytes());
                                }else {
                                    String[] split=text.split(":");
                                    String key="#"+split[0];
                                    String countext=split[1];
                                    //给特定用户发送消息
                                    Socket tomapssoSocket=mapsocket.get(key);
                                    if (null!=tomapssoSocket){
                                        OutputStream toStream=tomapssoSocket.getOutputStream();
                                        toStream.write(countext.getBytes("UTF-8"));
                                    }
                                }

//                              //群发
//                              for (Socket pluSocket :listsocket) {
//                                  if (pluSocket!=socket) {
//                                      OutputStream giveclic=pluSocket.getOutputStream();
//                                      giveclic.write(text.getBytes());
//                                  }else {
//                                      outputStream.write("收到".getBytes());
//                                  }
//                              }
                            }

                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                });
            }


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

服务端代码其实很简单,只要提供认证和类容就可以转发给指定的手机客户端了,下面我们来看看客户端代码吧,客户端其进入程序,就应该发一个认证连接服务端,然后在在客户端开启一个连接池。当有消息发送到大的是时候必须转发。这种东西就要写在service里面,然后定义动态广播,具体代码如下
activity类显示

package com.example.xutilsdemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.security.auth.PrivateCredentialPermission;

import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.lidroid.xutils.view.annotation.event.OnClick;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class SocketActivity extends Activity{
    @ViewInject(R.id.but_login)
    private Button but_login;
//  @ViewInject(R.id.but_outh)
//  private Button but_outh;
//  @ViewInject(R.id.but_service)
//  private Button but_service;
//  @ViewInject(R.id.but_lose)
//  private Button but_lose;
    @ViewInject(R.id.edit_context)
    private EditText edit_context;
//  @ViewInject(R.id.edit_outh)
//  private EditText edit_outh;
    private String ip="10.188.20.129";
    private int port=1001;
    private Socket socket;


    /**
     * 监听广播
     */
    private SocketPushBroadcastReservcer spbr=new SocketPushBroadcastReservcer() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (SocketPushBroadcastReservcer.ACTION_STRING.equals(intent.getAction())) {
                String contextString=intent.getStringExtra(SocketPushBroadcastReservcer.DATA_KEY);
                Log.i("获取消息", contextString);
                if (!contextString.equals(null)) {
                    Log.i("获取消息", contextString);
                    Toast.makeText(getApplicationContext(), contextString, Toast.LENGTH_LONG).show();
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewUtils.inject(this);
        startService(new Intent(this,SocketCorserviceService.class));
        IntentFilter intentFilter=new IntentFilter();
        //注册广播
        intentFilter.addAction(SocketPushBroadcastReservcer.ACTION_STRING);
        registerReceiver(spbr, intentFilter);
    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        unregisterReceiver(spbr);//注销广播

    }

    @OnClick(R.id.but_login)
    public void but_login(View v){
        if (TextUtils.isEmpty(edit_context.getText())) {
            return ;
        }
        try { 
//          OutputStream outputStream = socket.getOutputStream();
//          outputStream.write(edit_context.getText().toString().getBytes());
           ExecutorService executorService=Executors.newFixedThreadPool(2);
           executorService.execute(new Runnable() {

            @Override
            public void run() {
                SocketConnectorMessager.getConnectorMessager().
                   putRequest(edit_context.getText().toString().trim());                
            }
        });

        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

提供服务类
SocketConnector

package com.example.xutilsdemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * socket 类容提供者
 * @author double
 *
 */
public class SocketConnector {
    private String ip="10.188.20.129";
    private int port=1001;
    private Socket socket;
    SocketConnectorLinstre soLinstre;
    private ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(8);
    public SocketConnector(){

    }
    private class RwquestWork implements Runnable{

        @Override
        public void run() {
            try {
                OutputStream outputStream=socket.getOutputStream();
                while (true) {
                    String context=queue.take();
                    outputStream.write(context.getBytes("UTF-8"));  
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

//  /**
//   * 发送
//   */
//  public void send(String context){
//      OutputStream outputStream;
//      try {
//          outputStream = socket.getOutputStream();
//          outputStream.write(context.getBytes("UTF-8"));
//      } catch (Exception e) {
//          e.printStackTrace();
//      }
//  }
    public void putRequest(String context){
        System.out.println(">>>>>>>>>"+context);
        try {
            queue.put(context);
           System.out.println("queue.take()"+queue.take()); 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接
     */
    public void connector(){


            try {
                if (null==socket||socket.isClosed()){
                socket=new Socket(ip, port);
                }
                 new Thread(new RwquestWork()).start();
                ExecutorService executorService=Executors.newFixedThreadPool(3);
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {

                        try {
                            InputStream inputStream=socket.getInputStream();
                            byte[] buffer=new byte[1024];
                            int len;
                            while ((len=inputStream.read(buffer))!=-1) {
                                //服务端返回的结果
                                final String request=new String(buffer,0,len);
                                if (null!=soLinstre) {
                                    soLinstre.notfiyData(request);
                                }
                            }
//                          
//                          OutputStream outputStream=socket.getOutputStream();
//                          while (true) {
//                              String context=queue.take();
//                              System.out.println("---------"+context);
//                              outputStream.write(context.getBytes("UTF-8"));  
//                          }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }                       
                    }
                }); 

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    }
    /**
     * 断开
     */
    public void disConnector(){
        try {
            if (null==socket||socket.isClosed()){
                socket.close();
                socket=null;
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 认证
     */
    public  void Auth(String auth){
        OutputStream outputStream;
        try {
            outputStream = socket.getOutputStream();
            outputStream.write(auth.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void setSocketConnectorLinstre(SocketConnectorLinstre soLinstre ){
        this.soLinstre=soLinstre;
    }

    public interface SocketConnectorLinstre{
        public void notfiyData(String data);
    }
}

SocketConnectorMessager类主要用于认证

package com.example.xutilsdemo;

import com.example.xutilsdemo.SocketConnector.SocketConnectorLinstre;

/**
 * 消息提供者
 * @author double
 *
 */
public class SocketConnectorMessager implements SocketConnectorLinstre{
    private static  SocketConnectorMessager messager;
    private SocketConnector socketConnector;
     private SocketConnectorLinstre soLinstre;
    private SocketConnectorMessager(){

    }
    public static SocketConnectorMessager getConnectorMessager(){
        messager=new SocketConnectorMessager();
        return messager;
    }

    public void connect(String auth){
        socketConnector=new SocketConnector();
        socketConnector.setSocketConnectorLinstre(this);
        socketConnector.connector();//连接,   
        socketConnector.Auth(auth);//认证
    }
    public void putRequest(String request){
        if (socketConnector==null) {
            socketConnector=new SocketConnector();
        }
        socketConnector.connector();
        System.out.println("++++++++"+request);
        socketConnector.putRequest(request);
    }

    @Override
    public void notfiyData(String data) {
        if (soLinstre!=null) {
            soLinstre.notfiyData(data);
        }
    }

    public void setSocketConnectorLinstre(SocketConnectorLinstre soLinstre ){
        this.soLinstre=soLinstre;
    }

    public interface SocketConnectorLinstre{
        public void notfiyData(String data);
    }
}

SocketCorserviceService后台服务类

package com.example.xutilsdemo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;



import com.example.xutilsdemo.SocketConnectorMessager.SocketConnectorLinstre;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
/**
 * socket服务
 * @author double
 *
 */
public class SocketCorserviceService extends Service
implements SocketConnectorLinstre{
private SocketConnector socketConnector;
private SocketConnectorMessager socketConnectorMessager;
private ExecutorService exec=Executors.newFixedThreadPool(3);
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @SuppressWarnings("unused")
    @Override
    public void onCreate() {
        super.onCreate();
         socketConnectorMessager=SocketConnectorMessager.getConnectorMessager();

        exec.execute(new  Runnable() {
            public void run() {

                socketConnectorMessager.setSocketConnectorLinstre(SocketCorserviceService.this);
                socketConnectorMessager.connect("#A");
                //socketConnector=new SocketConnector();
            //  socketConnector.setSocketConnectorLinstre(SocketCorserviceService.this);
            //  socketConnector.connector();//连接,   
                //socketConnector.Auth("#A");//认证
            }
        });
        }

    @Override
    public void notfiyData(String data) {
        Intent intent=new Intent();
        intent.setAction(SocketPushBroadcastReservcer.ACTION_STRING);
        intent.putExtra(SocketPushBroadcastReservcer.DATA_KEY, data);
        sendBroadcast(intent);//发送广播
    }
}

广播监听
SocketPushBroadcastReservcer用于指定action动作

package com.example.xutilsdemo;

import android.content.BroadcastReceiver;
/**
 * 消息广播监听
 * @author twj
 *
 */
public abstract class SocketPushBroadcastReservcer extends BroadcastReceiver {

    public static final String ACTION_STRING="com.demo.action.text";
    public static final String DATA_KEY="data";
}

好了,吃饭去了,现在才去吃完饭,要源码的小伙伴留下邮箱

2016.05.29 .21 .34

阅读更多

扫码向博主提问

twjitm

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • java
  • spring
  • mybatis
  • hibernate
  • javaweb
去开通我的Chat快问
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页