使用Java编写Socket服务器,并且与Flex通信(一)
我使用的Eclipse插件swt design 6.9.1 for eclipse开发的Java客户端的swt应用
Socket服务器的Java代码如下:
package com.ruiri.app; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Shell; public class Test1 { private List list; protected Shell shell; private ServerSocket server; private Socket socket; private BufferedReader reader; private String str; /** * Launch the application * @param args */ public static void main(String[] args) { try { Test1 window = new Test1(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window */ public void open() { final Display display = Display.getDefault(); createContents(); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } /** * Create contents of the window */ protected void createContents() { shell = new Shell(); shell.setSize(286, 375); shell.setText("socket服务器"); final Button button = new Button(shell, SWT.NONE); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { Runnable runnable = new Runnable() { public void run() { try { server = new ServerSocket(719); Display.getDefault().asyncExec(new Runnable() { public void run() { list.add("服务器等待"); } }); while(true) { socket = server.accept(); Display.getDefault().asyncExec(new Runnable() { public void run() { list.add("已与客户机连接"); } }); reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8")); try { while(true) { str = reader.readLine(); if(str==null) break; Display.getDefault().asyncExec(new Runnable() { public void run() { list.add(str); } }); } } catch (Exception e) { e.printStackTrace(); } finally{ if(reader!=null) reader.close(); if(socket!=null) socket.close(); Display.getDefault().asyncExec(new Runnable() { public void run() { list.add("已与客户机断开"); } }); } } } catch (IOException e1) { e1.printStackTrace(); }finally{ if(server!=null) { try { server.close(); Display.getDefault().asyncExec(new Runnable() { public void run() { list.add("服务器断开"); } }); } catch (IOException e1) { e1.printStackTrace(); } } } } }; Thread thread = new Thread(runnable); thread.start(); } }); button.setText("开启socket"); button.setBounds(42, 316, 72, 22); list = new List(shell, SWT.V_SCROLL | SWT.BORDER | SWT.H_SCROLL); list.setBounds(26, 10, 217, 300); final Button button_1 = new Button(shell, SWT.NONE); button_1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { try { if(server!=null) { server.close(); server = null; } Display.getDefault().asyncExec(new Runnable() { public void run() { list.add("服务器断开"); } }); } catch (IOException e1) { e1.printStackTrace(); } } }); button_1.setText("关闭socket"); button_1.setBounds(154, 316, 72, 22); // } }
首先通过server = new ServerSocket(719);开启Socket服务,使用719端口
然后通过代码socket = server.accept(); 监测客户端连接,没有客户端联系的话,这个代码会堵塞到有客户端连接时才会继续往下走
所以这里使用了一个while(true)的死循环,只要有客户端连接就响应
再往下,reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
str = reader.readLine();是用来读取客户端发送过来的信息
注意到有这么一句if(str==null) break;这句很关键,至少在Flex调用Socket的时候非常有用,不用这个的话,关掉浏览器后,代码还是会通过reader.readLine();一直读取客户端发送的数据,陷入死循环,只是读到的值是null,所以这里通过这句代码在关闭浏览器的时候跳出循环
上面的代码虽然有点长,其实关键的代码不多。代码里面用到了启用多线程的方式,我的另外一篇文章有讲解:http://www.cnblogs.com/modou/articles/1525941.html
执行上面的代码,开启Socket服务以后,下面我们来编写Flex代码,编写客户端调用程序:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="application1_creationCompleteHandler(event)"> <s:layout> <s:BasicLayout/> </s:layout> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; private var socket:Socket; protected function application1_creationCompleteHandler(event:FlexEvent):void { socket=new Socket();//创建Socket对象 socket.connect("localhost",719); //连接服务器 socket.addEventListener(Event.CONNECT,connectFun);//监听是否连接上服务器 socket.addEventListener(Event.CLOSE,closeFun);//监听套接字连接是否关闭 } private function connectFun(event:Event):void { jText.text+="已经成功连接到服务器!\n"; } private function closeFun(event:Event):void { jText.text+="和服务器断开!\n" } protected function button2_clickHandler(event:MouseEvent):void { var message:ByteArray=new ByteArray();//新建一个ByteArray存放数据 message.writeUTFBytes(msg.text +"\r\n");//写入数据,writeUTFBytes方法,以utf-8格式传数据避免中文乱码 socket.writeBytes(message); //写入Socket的缓冲区 socket.flush(); //调用flush方法发送信息 msg.text=""; //清空发言框 } ]]> </fx:Script> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <s:TextArea id="jText" x="139" y="129"/> <s:TextInput id="msg" x="139" y="325" width="188"/> <s:Button x="361" y="326" label="按钮" click="button2_clickHandler(event)"/> </s:Application>