使用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>
到此,一个完整的例子就完成了。我在学习Socket使用的时候,参考了这篇文章,在此表示感谢:http://www.javaeye.com/topic/607169

posted @ 2010-12-07 17:44  魔豆  阅读(1025)  评论(0编辑  收藏  举报