您的位置:首页 > 理论基础 > 计算机网络

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

2016-05-29 21:30 731 查看
最近要面试了,想练习一下网络编程吧,想想来搞搞实现太手机聊天功能吧,其实聊天功能有集成好的框架,有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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket 网络编程