最近要面试了,想练习一下网络编程吧,想想来搞搞实现太手机聊天功能吧,其实聊天功能有集成好的框架,有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 Listlistsocket=new LinkedList();
private static Mapmapsocket=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 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