Android socket编程 以非阻塞I.docx

上传人:b****5 文档编号:30685425 上传时间:2023-08-19 格式:DOCX 页数:17 大小:233.58KB
下载 相关 举报
Android socket编程 以非阻塞I.docx_第1页
第1页 / 共17页
Android socket编程 以非阻塞I.docx_第2页
第2页 / 共17页
Android socket编程 以非阻塞I.docx_第3页
第3页 / 共17页
Android socket编程 以非阻塞I.docx_第4页
第4页 / 共17页
Android socket编程 以非阻塞I.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

Android socket编程 以非阻塞I.docx

《Android socket编程 以非阻塞I.docx》由会员分享,可在线阅读,更多相关《Android socket编程 以非阻塞I.docx(17页珍藏版)》请在冰豆网上搜索。

Android socket编程 以非阻塞I.docx

Androidsocket编程以非阻塞I

Androidsocket编程以非阻塞I/O服务器及Service为例

来源:

中国手机开发网2010年01月25日字体:

[小大]点击推荐给好友

关键字:

  之前采用聊天敲门的方式来介绍Socket通信,有两个不足的地方,

  1.服务器会造成IO的阻塞

  即服务器一旦执行server.accept();

  将一直处于阻塞状态,直到有客户端请求连接。

  2.服务器端没有建立用户列表,无法将某一客户端发送的消息广播给所有正在连接的客户端。

  就好象是一个人自说自话,自己发送给客户端,自己接收服务器返回的消息。

  基于以上两点,我改进了我的程序。

  服务器端的改进:

  1.通过采用socketchannel的非阻塞方式进行通信

  2.建立Userlist客户端的哈希表,存储已连接客户端的ip地址和服务器为其分发的socketchannel

  客户端的改进:

  1.采用Service与服务器端进行连接,发送数据,实时监听服务器返回的数据。

  流程图:

  需要改进的地方

  服务器端:

  1.当一个客户端断开连接以后,另一个客户端在收到消息之前也断开连接,而此时服务器正在向客户端发送消息,

  因此,服务器的Thread.sleep时间不能太长,但也不能太短,因为考虑到服务器的负荷问题。

  2.服务器容错处理机制需要改进。

  客户端:

  1.将Notificationbar改为其他更为直观方式刷新显示。

  2.容错处理机制的处理。

  下面是效果图:

  服务器端:

  dos客户端:

  Android客户端:

  效果图的意思是,Android的客户端通过绑定Service与服务器端进行了连接,并发送消息。

服务器向所有正在连接的客户端广播消息。

  之后,Dos终端也进行连接,并发送消息,服务器接到消息后向所有正在连接的客户端广播消息(其中包括在线的android手机)

第1页第2页第3页第4页第5页第6页

  之前采用聊天敲门的方式来介绍Socket通信,有两个不足的地方,

  1.服务器会造成IO的阻塞

  即服务器一旦执行server.accept();

  将一直处于阻塞状态,直到有客户端请求连接。

  2.服务器端没有建立用户列表,无法将某一客户端发送的消息广播给所有正在连接的客户端。

  就好象是一个人自说自话,自己发送给客户端,自己接收服务器返回的消息。

  基于以上两点,我改进了我的程序。

  服务器端的改进:

  1.通过采用socketchannel的非阻塞方式进行通信

  2.建立Userlist客户端的哈希表,存储已连接客户端的ip地址和服务器为其分发的socketchannel

  客户端的改进:

  1.采用Service与服务器端进行连接,发送数据,实时监听服务器返回的数据。

  流程图:

  需要改进的地方

  服务器端:

  1.当一个客户端断开连接以后,另一个客户端在收到消息之前也断开连接,而此时服务器正在向客户端发送消息,

  因此,服务器的Thread.sleep时间不能太长,但也不能太短,因为考虑到服务器的负荷问题。

  2.服务器容错处理机制需要改进。

  客户端:

  1.将Notificationbar改为其他更为直观方式刷新显示。

  2.容错处理机制的处理。

  下面是效果图:

  服务器端:

  dos客户端:

  Android客户端:

  效果图的意思是,Android的客户端通过绑定Service与服务器端进行了连接,并发送消息。

服务器向所有正在连接的客户端广播消息。

  之后,Dos终端也进行连接,并发送消息,服务器接到消息后向所有正在连接的客户端广播消息(其中包括在线的android手机)

第1页第2页第3页第4页第5页第6页

  接上页

  源代码如下:

  Server端:

  packagecom.android.Yao;

  importjava.io.*;

  importjava.nio.*;

  importjava.nio.channels.*;

  import.*;

  importjava.util.*;

  importjava.nio.charset.*;

  importjava.lang.*;

  publicclassYaoChatServer

  {

  publicSelectorsel=null;

  publicServerSocketChannelserver=null;

  publicSocketChannelsocket=null;

  publicintthisport=4900;

  privateStringresult=null;

  privateHashtableuserlists;

  privateSocketChannelreadingsocket=null;

  publicYaoChatServer()

  {

  System.out.println("Insidestartserver");

  }

  publicYaoChatServer(intport)

  {

  System.out.println("Insidestartserver");

  thisport=port;

  }

  publicvoidinitializeOperations()throwsIOException,UnknownHostException

  {

  System.out.println("Insideinitialization");

  sel=Selector.open();

  server=ServerSocketChannel.open();

  server.configureBlocking(false);

  InetAddressia=InetAddress.getLocalHost();

  InetSocketAddressisa=newInetSocketAddress(ia,thisport);

  server.socket().bind(isa);

  userlists=newHashtable();

  }

  publicvoidstartServer()throwsIOException

  {

  initializeOperations();

  server.register(sel,SelectionKey.OP_ACCEPT);

  while(sel.select()>0)

  {

  SetreadyKeys=sel.selectedKeys();

  Iteratorit=readyKeys.iterator();

  while(it.hasNext())

  {

  SelectionKeykey=(SelectionKey)it.next();

  it.remove();

  if(key.isAcceptable())

  {

  ServerSocketChannelssc=(ServerSocketChannel)key.channel();

  socket=(SocketChannel)ssc.accept();

  socket.configureBlocking(false);

  Stringsocketname=socket.socket().getRemoteSocketAddress().toString();

  socket.register(sel,SelectionKey.OP_WRITE);

  userlists.put(socketname,socket);

  System.out.println(socketname+"isconnected!

");

  }

  if(key.isWritable()){

  readingsocket=(SocketChannel)key.channel();

  Stringret=readMessage(readingsocket);

  if(ret.equalsIgnoreCase("@@@@@isgoingtosaygoodbye!

"))

  {

  key.cancel();

  readingsocket.close();

  userlists.remove(readingsocket.socket().getRemoteSocketAddress().toString());

  System.out.println("sendservermsg:

"+ret.replace("@@@@@",readingsocket.socket().getRemoteSocketAddress().toString()));

  sendMessage(ret.replace("@@@@@",readingsocket.socket().getRemoteSocketAddress().toString()));

  }

  elseif(ret.length()>0){

  System.out.println("sendservermsg:

"+ret);

  sendMessage(ret);

  }

  }

  }

  }

  }

  publicvoidsendMessage(Stringmsg)throwsIOException

  {

  ByteBufferbuffer=ByteBuffer.allocate(1024);

  buffer=ByteBuffer.wrap(msg.getBytes());

  //ByteBufferbuffer=ByteBuffer.wrap(msg.getBytes("UTF-8"));

  Collectionchannels=userlists.values();

  SocketChannelsc;

  for(Objecto:

channels){

  sc=(SocketChannel)o;

  sc.write(buffer);

  buffer.flip();

  try{

  Thread.sleep(500);

  }catch(InterruptedExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  }

  publicStringreadMessage(SocketChannelsc)

  {

  intnBytes=0;

  ByteBufferbuf=ByteBuffer.allocate(1024);

  try{

  nBytes=sc.read(buf);

  buf.flip();

  Charsetcharset=Charset.forName("UTF-8");

  CharsetDecoderdecoder=charset.newDecoder();

  CharBuffercharBuffer=decoder.decode(buf);

  result=charBuffer.toString();

  }catch(IOExceptione){

  result="@@@@@isgoingtosaygoodbye!

";

  }

  returnresult;

  }

  publicstaticvoidmain(Stringargs[])

  {

  YaoChatServernb=newYaoChatServer();

  try

  {

  nb.startServer();

  }

  catch(IOExceptione)

  {

  e.printStackTrace();

  System.exit(-1);

  }

  }

  }

  Android客户端的Service类:

  packagecom.android.Yao;

  importjava.io.BufferedReader;

  importjava.io.IOException;

  importjava.io.InputStreamReader;

  import.InetSocketAddress;

  importjava.nio.ByteBuffer;

  importjava.nio.CharBuffer;

  importjava.nio.channels.SocketChannel;

  importjava.nio.charset.CharacterCodingException;

  importjava.nio.charset.Charset;

  importjava.nio.charset.CharsetDecoder;

  importjava.util.Collection;

  importandroid.app.Notification;

  importandroid.app.NotificationManager;

  importandroid.app.PendingIntent;

  importandroid.app.Service;

  importandroid.content.Context;

  importandroid.content.Intent;

  importandroid.os.Binder;

  importandroid.os.IBinder;

  publicclassReceiveMessageextendsService{

  privateSocketChannelclient=null;

  privateInetSocketAddressisa=null;

  privateStringmessage="";

  publicvoidonCreate(){

  super.onCreate();

  ConnectToServer();

  StartServerListener();

  }

  publicvoidonDestroy(){

  super.onDestroy();

  DisConnectToServer();

  }

  publicvoidonStart(Intentintent,intstartId){

  super.onStart(intent,startId);

  }

  /*

  *IBinder方法,LocalBinder类,mBinder接口这三项用于

  *Activity进行Service的绑定,点击发送消息按钮之后触发绑定

  *并通过Intent将Activity中的EditText的值

  *传送到Service中向服务器发送

  *

  **/

  publicIBinderonBind(Intentintent){

  message=intent.getStringExtra("chatmessage");

  if(message.length()>0)

  {

  SendMessageToServer(message);

  }

  returnmBinder;

  }

  publicclassLocalBinderextendsBinder{

  ReceiveMessagegetService(){

  returnReceiveMessage.this;

  }

  }

  privatefinalIBindermBinder=newLocalBinder();

  //用于链接服务器端

  publicvoidConnectToServer()

  {

  try{

  client=SocketChannel.open();

  isa=newInetSocketAddress("192.168.0.107",4900);

  client.connect(isa);

  client.configureBlocking(false);

  }catch(IOExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  //断开与服务器端的链接

  publicvoidDisConnectToServer()

  {

  try{

  client.close();

  }catch(IOExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  //启动服务器端的监听线程,从Server端接收消息

  publicvoidStartServerListener()

  {

  ServerListenera=newServerListener();

  a.start();

  }

  //向Server端发送消息

  publicvoidSendMessageToServer(Stringmsg)

  {

  try

  {

  ByteBufferbytebuf=ByteBuffer.allocate(1024);

  bytebuf=ByteBuffer.wrap(msg.getBytes("UTF-8"));

  client.write(bytebuf);

  bytebuf.flip();

  }

  catch(IOExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  privatevoidshownotification(Stringtab)

  {

  NotificationManagerbarmanager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

  Notificationmsg=newNotification(android.R.drawable.stat_notify_chat,"AMessageComing!

",System.currentTimeMillis());

  PendingIntentcontentIntent=PendingIntent.getActivity(this,0,newIntent(this,YaoChatRoomAndroid.class),PendingIntent.FLAG_ONE_SHOT);

  msg.setLatestEventInfo(this,"Message","Message:

"+tab,contentIntent);

  barmanager.notify(0,msg);

  }

  privateclassServerListenerextendsThread

  {

  publicvoidrun(){

  try{

  //无线循环,监听服务器,如果有不为空的信息送达,则更新Activity的UI

  while(true)

  {

  ByteBufferbuf=ByteBuffer.allocate(1024);

  client.read(buf);

  buf.flip();

  Charsetcharset=Charset.forName("UTF-8");

  CharsetDecoderdecoder=charset.newDecoder();

  CharBuffercharBuffer;

  charBuffer=decoder.decode(buf);

  Stringresult=charBuffer.toString();

  if(result.length()>0)

  shownotification(result);

  }

  }

  catch(CharacterCodingExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  catch(IOExceptione){

  //TODOAuto-generatedcatchblock

  e.printStackTrace();

  }

  }

  }

  }

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1