﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-eric-随笔分类-Socket</title><link>http://www.blogjava.net/jjshcc/category/46362.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 20 Sep 2010 07:48:15 GMT</lastBuildDate><pubDate>Mon, 20 Sep 2010 07:48:15 GMT</pubDate><ttl>60</ttl><item><title>flex与JAVA的SOCKET通信</title><link>http://www.blogjava.net/jjshcc/archive/2010/09/19/332424.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Sun, 19 Sep 2010 04:33:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2010/09/19/332424.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/332424.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2010/09/19/332424.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/332424.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/332424.html</trackback:ping><description><![CDATA[<p>建立连接<br />
既然是通信，当然第一步就是要建立连接啦。我们还是用最简单的看代码的方式来开始我们的连接。</p>
<p>==========================================<br />
==服务端代码：Jserver1.java<br />
==========================================</p>
<p>import java.net.*;<br />
import java.io.*;<br />
public class Jserver1 {<br />
public static void main(String[] args) {<br />
ServerSocket server=null;<br />
try{<br />
&nbsp;&nbsp; server=new ServerSocket(719);//在端口719建立一个服务器套接字对象<br />
&nbsp; System.out.println("服务端等待");<br />
&nbsp; while(true){<br />
&nbsp;&nbsp; System.out.println("等待客户机");<br />
&nbsp;&nbsp; Socket newSocket=server.accept();//客户端向我们建立的服务器套接字发送连接请求,则向下执行<br />
&nbsp;&nbsp; System.out.println("已与客户机连接");<br />
&nbsp; }<br />
}catch(IOException ie)<br />
{<br />
&nbsp; System.out.println(ie);<br />
}finally{<br />
&nbsp; try<br />
&nbsp; {<br />
&nbsp;&nbsp; if(server!=null) server.close();//关闭服务器套接字。为什么要用finally关键字来做这个事呢？HOHO thinking in java里大师已经说得很清楚了，就是无论出现什么异常，都保证我们的服务端套接字能被关闭。<br />
&nbsp; }catch(IOException ie){}<br />
}<br />
}<br />
&nbsp;嘎嘎，怎么样 注释写得够清楚了吧？OK 让我们编译运行，得到的结果应该如图：</p>
<p>OK 再让我们来看看客户端的代码是怎么样的：<br />
==========================================<br />
==客户端代码：Jclient1.mxml<br />
===================================================</p>
<p><br />
&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creati f width="349" height="326"&gt;<br />
&lt;mx:Script&gt;<br />
&nbsp; &lt;![CDATA[<br />
&nbsp; import flash.net.Socket;<br />
&nbsp; private var socket:Socket;<br />
&nbsp; internal function initApp():void<br />
&nbsp; {<br />
&nbsp;&nbsp; socket=new Socket();//创建Socket对象<br />
&nbsp;&nbsp; socket.connect("localhost",719);　　//连接服务器<br />
&nbsp;&nbsp; socket.addEventListener(Event.CONNECT,connectFun);//监听是否连接上服务器<br />
&nbsp;&nbsp; socket.addEventListener(Event.CLOSE,closeFun);//监听套接字连接是否关闭<br />
&nbsp; }<br />
&nbsp; private function connectFun(event:Event):void<br />
&nbsp; {<br />
&nbsp;&nbsp; jText.text+="已经成功连接到服务器！\n";<br />
&nbsp; }</p>
<p>&nbsp; private function closeFun(event:Event):void<br />
&nbsp; {<br />
&nbsp;&nbsp; jText.text+="和服务器断开!\n"<br />
&nbsp; }<br />
&nbsp; ]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;mx:TextArea x="10" y="10" width="327" height="309" id="jText"/&gt;<br />
&lt;/mx:Application&gt;</p>
<p>界面非常简单啦，其实就是一个TextArea来显示连接的结果而已，运行的结果如下图（注意，服务端也应该在运行！）：</p>
<p>在as3.0中,所有和网络通信有关的类都位于flash.net包中，这里使用的是Socket类对象。<br />
==========================================<br />
==我们来详细说明一下上面用到的Socket类：<br />
==========================================</p>
<p>Socket对象的常用创建方法有下面2种：<br />
var socket:Socket=new Socket();//例一<br />
或者<br />
var socket:Socket=new Socket("localhost",719);//例二.这条语句设置了服务器地址为localhost 端口是719</p>
<p>当指定了了服务器地址和端口，Socket对象将自动开始连接服务器。如果不指定，则需要条用connect方法才开始执行连接动作，意思就是,例二的代码和下面的代码是等效的：</p>
<p>var socket:Socket=new Socket();<br />
socket.connect("localhost",719);<br />
完成连接动作后，接下来要获取服务端得返回信息。<br />
Socket对象和URLLOADER啊之类的对象都是一样，利用事件机制来处理服务器端的信息，我们只要给Socket对象添加相关的事件监听函数就可以捕捉到服务器端的信息，Socket对象的事件主要有：<br />
１　Event.CLOSE　连接中断事件。<br />
２　Event.CONNECT 连接状态事件，表示已经成功连接了服务器。<br />
３　IOErrorEvent.IO_ERROR　信息传递错误事件，一般是由服务器地址错误引起的。<br />
４　ProgressEvent.SOCKET_DATA　服务器信息事件，当收到服务器的新信息时被触发。</p>
<p>==========================================</p>
<p>哈哈，经过上面的代码，我们的服务端MM和客户端GG终于通过Socket这个缘分宿命的相遇了！接下来会发生什么？我们继续往下看~~<br />
三、第一封情书（客户端发送消息，服务端接受消息）</p>
<p>&nbsp;</p>
<p>客户端GG在遇到服务端MM以后，终日变得茶饭不思，在折磨掉了无数根头发以后，客户端GG终于下定决心，要向服务端MM送出第一封情书啦！</p>
<p>既然是客户端GG送出情书，那我们先来看他到底是怎么做的：<br />
==========================================<br />
==客户端代码：Jclient2.mxml<br />
==========================================</p>
<p>&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()"&gt;<br />
&lt;mx:Script&gt;<br />
&lt;![CDATA[<br />
import flash.net.Socket;<br />
import flash.utils.ByteArray;</p>
<p>private var socket:Socket=new Socket();　//定义Socket,准备好情书的信封<br />
//初始化程序<br />
internal function initApp():void<br />
{<br />
socket.connect("localhost",719); //连接服务器<br />
socket.addEventListener(Event.CONNECT,funConnect); //监听是否连接<br />
socket.addEventListener(Event.CLOSE,funClose); //监听连接关闭<br />
}<br />
internal function funConnect(event:Event):void<br />
{<br />
myText.text+="连接已建立 \n";<br />
}<br />
internal function funClose(event:Event):void<br />
{<br />
myText.text+="连接已关闭 \n";<br />
}</p>
<p>internal function sendMessage(msg:String):void//发送数据对应按钮click事件<br />
{<br />
var message:ByteArray=new ByteArray();//新建一个ByteArray存放数据<br />
message.writeUTFBytes(msg +"\r\n");//写入数据，writeUTFBytes方法，以utf-8格式传数据避免中文乱码<br />
socket.writeBytes(message);　 //写入Socket的缓冲区<br />
socket.flush();　　//调用flush方法发送信息<br />
myText.text+=msg+"\r\n";　　//在客户端屏幕上输出发送的内容<br />
myInput.text=""; //清空发言框<br />
}<br />
]]&gt;<br />
&lt;/mx:Script&gt;<br />
&lt;mx:TextArea x="10" y="10" width="703" height="263" id="loveText"/&gt;<br />
&lt;mx:TextInput x="10" y="297" width="605" id="loveInput"/&gt;<br />
&lt;mx:Button x="648" y="297" label="发送情书" id="sendBtn" click="sendMessage(loveInput.text)"/&gt;<br />
&lt;/mx:Application&gt;</p>
<p>嘎嘎，情书的做法就上面那面简单，注释已经写得很清楚了，就不多说了。</p>
<p>OK，客户端GG的情书倒是送出去了，我们就来看看服务端MM是怎么接受这封情书的呢？</p>
<p><br />
OK，客户端GG的情书倒是送出去了，我们就来看看服务端MM是怎么接受这封情书的呢？<br />
==========================================<br />
==服务端代码：Jserver2.java<br />
==========================================<br />
</p>
<p>import java.net.*;<br />
import java.io.*;<br />
public class Jserver2{<br />
private BufferedReader reader;　//负责输入<br />
private ServerSocket server;　　 //服务器套接字<br />
private Socket socket;　　　　　 //套接字<br />
public Server2(){}　　//缺省构造函数<br />
void startServer()　　//启动服务器<br />
{<br />
try<br />
{<br />
server=new ServerSocket(719);　　　 //创建服务器套接字<br />
System.out.println("服务器套接字建立完毕");<br />
while(true)<br />
{<br />
　　System.out.println("等待客户端GG");<br />
　　socket=server.accept();　//若客户端GG提出连接请求，与socket连接<br />
　　System.out.println("完成与客户端的连接");<br />
reader=new BufferedReader(new　InputStreamReader(socket.getInputStream(),"UTF-8")); //获取socket输入流，&#8220;utf-8&#8221;这个编码设置是为了更好显示中文 <br />
getMessage();//读取来自客户端的数据，并输出至画面上<br />
}<br />
}catch(Exception e)<br />
{<br />
System.out.println(e);<br />
}finally{<br />
try<br />
{<br />
if(server!=null) server.close();//关闭服务器套接字。<br />
}catch(IOException ie){}<br />
}<br />
}<br />
void getMessage()　　//读取来自套接字的信息<br />
{<br />
try<br />
{<br />
while(true)　　　 //循环<br />
{<br />
System.out.println("客户端GG说："+reader.readLine());<br />
}<br />
}catch(Exception e){}<br />
finally{<br />
System.out.println("客户端中断连接");<br />
try<br />
{<br />
if(reader!=null) reader.close();　//关闭套接字的输入流<br />
if(socket!=null) socket.close();　　//关闭套接字<br />
reader=null;<br />
socket=null;<br />
}catch(Exception e){}<br />
}<br />
}<br />
public static void main(String[] args)<br />
{<br />
Server2 server=new Server2();<br />
server.startServer();<br />
}</p>
<p>}</p>
<p>哈哈，我们运行来看看，我们的客户端GG的情书能否顺利到达服务端MM的手中呢？<br />
运行结果如下：</p>
<p><br />
HOHO 看样子我们的客户端GG的情书，服务端MM是顺利接受到啦。</p>
<p>&nbsp;</p>
<p>四、服务端MM的心思（多客户端通信）</p>
<p><br />
在服务端MM收到客户端GG的情书以后，突然发现自己原来还是蛮受欢迎的呢。但是有句俗话说的好，那就是&#8220;不能为了一棵树放弃一片森林&#8221;。所以服务端MM就想，能不能多接受几个客户端GG的情书呢？（真TMD贱。。。）</p>
<p>OK，既然服务端MM有了这个需求（虽然是很贱的需求），那我们就要来满足她！</p>
<p>来看服务端的代码:<br />
=========================================<br />
==Jserver3.java<br />
=========================================</p>
<p>&nbsp;</p>
<p>import java.net.*;<br />
import java.io.*;<br />
import java.util.*;</p>
<p>public class Jserver3 {<br />
private ServerSocket server;<br />
List sManager = new ArrayList();</p>
<p>public Jserver3(){}<br />
void startServer()　//运行服务器<br />
{<br />
try<br />
{<br />
server=new ServerSocket(719);<br />
System.out.println("服务器套接字已创建成功！");<br />
while(true)<br />
{<br />
Socket socket=server.accept();<br />
System.out.println("已经与客户端连接");<br />
new J_Thread(socket).start();<br />
sManager.add(socket);<br />
System.out.println("当前客户端连结数："+sManager.size());<br />
}<br />
}catch(Exception e){}finally<br />
{<br />
try<br />
{<br />
server.close();<br />
}catch(Exception e){}<br />
}<br />
}<br />
public static void main(String[] args) {</p>
<p>Jserver3 server=new Jserver3();<br />
server.startServer();<br />
}<br />
class J_Thread extends Thread　　//与客户端进行通信的线程类<br />
{<br />
Socket socket;　　 //套接字引用变量<br />
private DataInputStream reader;　　 //套接字输入流<br />
private DataOutputStream writer;　 //套接字输出流<br />
J_Thread(Socket socket)　　 //构造函数<br />
{<br />
this.socket=socket;<br />
}<br />
public void run()<br />
{<br />
try<br />
{</p>
<p>reader=new DataInputStream(socket.getInputStream());//获取套接字的输入流<br />
writer=new DataOutputStream(socket.getOutputStream());//获取套接字的输出流<br />
String msg;<br />
while((msg=reader.readUTF())!=null)//如果收到客户端发来的数据<br />
{<br />
//向客户端发送信息<br />
writer.writeUTF("您的情书已经收到");<br />
writer.flush();<br />
System.out.println("来自客户端："+msg);</p>
<p>}<br />
}catch(Exception e){}finally<br />
{<br />
try<br />
{<br />
sManager.remove(socket); 　//删除套接字<br />
//关闭输入输出流及套接字<br />
if(reader!=null)reader.close();<br />
if(writer!=null)writer.close();<br />
if(socket!=null)socket.close();<br />
reader=null;<br />
writer=null;<br />
socket=null;</p>
<p>System.out.println("客户端离开");//向屏幕输出相关信息<br />
System.out.println("当前客户端的连接数："+sManager.size());<br />
}catch(Exception e){}<br />
}<br />
}<br />
}</p>
<p>}</p>
<p>嘎嘎 在这段代码里，服务端MM为每一个连接的客户端GG分配一个单独的线程，而每一个线程里都持有对应的客户端GG的Socket对象。SO，通过这些多线程，服务端MM就练就了一心N用的功力，可以同时接受N个客户端GG发来的情书了（ ，真的太贱了。。。。）</p>
<p>客户端的代码和上面的客户端代码一模一样的，这里就不多说啦！</p>
<p>&nbsp;</p>
<p><br />
好了，在这里就简单的给大家介绍了如何实现java和flash（flex）实现socket通信的简单功能。有时间的话，再给大家来个简单的聊天室实现（那个时候的服务端MM就更贱了，不仅收着N多客户端GG的情书，竟然还把情书广播给所有的客户端GG，BS！）。嘎嘎 其实原理就是上面所说的这些，大家自己都可以尝试下。</p>
<img src ="http://www.blogjava.net/jjshcc/aggbug/332424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2010-09-19 12:33 <a href="http://www.blogjava.net/jjshcc/archive/2010/09/19/332424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>