| |
| 如何用Java实现网络中国象棋室(二) |
| |
发布者: 发布时间:2007-11-26 |
|
|
2、象棋服务主类,接收用户登录连接,和用户的数据处理和转发:package sunstudio;import sunstudio.event.*;import java.util.*;import java.net.*;import java.io.*;import sunstudio.util.*;public class ChessServer implements LoginListener{int tablecount=20;ChessTable[] tb=new ChessTable[tablecount];Hashtable userlist=new Hashtable();public ServerSocket ss=null;ChessLogin cl=null;public static ChessServer hwnd=null;public static void main(String[] args){ChessServer server=new ChessServer();}public ChessServer(){for(int i=0;i 19)return;ChessUser user=(ChessUser)tb[tableID].remove(new Integer(userID));if(user!=null){user.tableID=-1;user.state=-1;}}public boolean addUser(ChessUser user){if(userlist.contains(new Integer(user.userID)))return false;userlist.put(new Integer(user.userID),user);return true;}public void removeUser(int userID){ChessUser user=(ChessUser)userlist.remove(new Integer(userID));if(user!=null){user.close();user=null;}}public void sendToRoom(byte[] h,int l,byte[] d){for(Enumeration enu=userlist.elements();enu.hasMoreElements();){try{((ChessUser)enu.nextElement()).sender.sendData(h,d,l);}catch(Exception e){}}}public void sendToTable(byte[] h,int l,byte[] d){for(Enumeration enu=tb[h[3]].elements();enu.hasMoreElements();){try{((ChessUser)enu.nextElement()).sender.sendData(h,d,l);}catch(Exception e){}}}public byte[] getUserListData(){byte[] ul=new byte[userlist.size()*14];int ptr=0;for(Enumeration enu=userlist.elements();enu.hasMoreElements();){ChessUser user=(ChessUser)enu.nextElement();System.arraycopy(user.getBytes(),0,ul,ptr,14);ptr+=14;}return ul;}public void onUserPackageArrived(byte[] h,int l,byte[] d){synchronized(this){try{int userID=Convert.byteToInt(h[5],h[6],h[7],h[8]);ChessUser user=null;user=(ChessUser)userlist.get(new Integer(userID));switch(h[0]){case 0://进入游戏桌//user.setState(h[4]);System.out.println("用户"+user.username+"进入"+h[3]+"号游戏桌"+(h[4]%2==0?"执红":"执黑")+"!");h[4]=(byte)addTableUser(h[3],userID,h[4]);break;case 1://user.setState(-1);System.out.println("用户"+user.username+"退出"+h[3]+"号游戏桌!");removeTableUser(h[3],userID);break;/////////////////////////////////////case 2://走步sendToTable(h,l,d);return;case 3://求和sendToTable(h,l,d);return;case 4://认输sendToTable(h,l,d);return;case 5://悔棋sendToTable(h,l,d);return;/////////////////////////////////////case 6://用户列表break;case 7://新用户登录break;case 8://用户退出if(user==null)return;try{removeTableUser(user.tableID,user.userID);}catch(Exception ex){ex.printStackTrace();}try{removeUser(user.userID);}catch(Exception exx){exx.printStackTrace();}System.out.println("用户退出象棋室");break;case 9://聊天信息sendToTable(h,l,d);return;}sendToRoom(h,l,d);}catch(Exception e){e.printStackTrace();}}}public void onLoginEvent(LoginEvent evt){System.out.println(evt.username+","+evt.userID);ChessUser user=new ChessUser(evt.username,evt.userID,evt.socket);if(user.init()){System.out.println("用户进入象棋室");sendToRoom(new byte[]{7,14,0,0,0,0,0,0,0,0,0,0},14,user.getBytes());//新用户登录if(addUser(user)){user.start();try{user.sender.sendUserListData(getUserListData());}catch(Exception e){}}}//else销毁用户对象}}3、象棋用户类,实现用户信息的存储和用户数据的接收和转发:package sunstudio;import java.net.*;import java.io.*;import sunstudio.netlib.*;import sunstudio.util.*;public class ChessUser implements TcpDataListener{public String username=null;public int userID=-1,tableID=-1;public int state=-1;//0:执红走棋1:执黑走棋2:看红走棋3:看黑走棋byte[] data=new byte[14];Socket socket=null;TcpDataReceiver receiver=null;TcpDataSender sender=null;public ChessUser(String un,int ui,Socket st){username=un;userID=ui;socket=st;System.arraycopy(username.getBytes(),0,data,0,Math.min(8,username.getBytes().length));System.arraycopy(Convert.intToBytes(ui),0,data,8,4);data[12]=(byte)-1;data[13]=(byte)-1;}public boolean init(){try{sender=new TcpDataSender(socket.getOutputStream());receiver=new TcpDataReceiver(socket.getInputStream());receiver.addTcpDataListener(this);return true;}catch(IOException e){}return false;}public void setState(int stat){state=stat;data[13]=(byte)stat;}public void start(){try{sender.sendLoginBack(userID);receiver.start();}catch(Exception e){}}public void onTcpDataArrived(TcpDataEvent evt){ChessServer.hwnd.onUserPackageArrived(evt.getHeader(),evt.getDataLen(),evt.getData());}public byte[] getBytes(){return data;}public void close(){try{if(socket!=null){socket.close();socket=null;}}catch(Exception e){}try{if(receiver!=null){receiver.setRunning(false);receiver=null;}}catch(Exception e){}try{if(sender!=null)sender=null;}catch(Exception e){}}}4、TCP数据接收器:package sunstudio.netlib;import java.util.*;import java.net.*;import java.io.*;import sunstudio.util.*;public class TcpDataReceiver extends Thread{Vector listeners=new Vector();boolean isrunning=true;InputStream is=null;byte[] h=new byte[12];byte[] d=new byte[1024];int l=0;public TcpDataReceiver(InputStream s){is=s;}public void run(){try{while(isrunning){HttpInputStream.readBytes(is,12,h);l=Convert.byteToShort(h[1],h[2]);if(l>0)HttpInputStream.readBytes(is,l,d);if(l>0)notifyListeners(h,l,d);else if(l==0)notifyListeners(h,0,null);else throw new IOException();}}catch(IOException e){System.out.println("读取流数据异常!");//异常处理,关闭socket}}public void addTcpDataListener(TcpDataListener hrl){listeners.addElement(hrl);}synchronized void notifyListeners(byte[] hh,int ll,byte[] dd){TcpDataEvent evt=new TcpDataEvent(hh,ll,dd);for(Enumeration enumeration=listeners.elements();enumeration.hasMoreElements();((TcpDataListener)enumeration.nextElement()).onTcpDataArrived(evt));}public void setRunning(boolean rr){this.isrunning=rr;}}5、TCP数据监听接口:package sunstudio.netlib;public interface TcpDataListener{public void onTcpDataArrived(TcpDataEvent evt);}6、TCP数据包接收事件:package sunstudio.netlib;import java.net.*;public class TcpDataEvent{byte[] head=null;int datalen=-1;byte[] datas=null;public TcpDataEvent(byte[] h,int len,byte[] dt){head=h;datalen=len;datas=dt;}public byte[] getHeader(){return head;}public byte[] getData(){return datas;}public int getDataLen(){return datalen;}}7、TCP数据发送器:package sunstudio.netlib;import java.io.*;import sunstudio.util.*;public class TcpDataSender{OutputStream os;byte[] d=new byte[1024];int l;public TcpDataSender(OutputStream ost){os=ost;}public void sendLoginBack(int userID){byte[] cd=new byte[9];System.arraycopy(Convert.intToBytes(userID),0,cd,2,4);sendeHeader((byte)10,cd);}public void sendeHeader(byte cmdType,byte[] cData){try{d[0]=cmdType;//登录System.arraycopy(Convert.shortToBytes((short)0),0,d,1,2);System.arraycopy(cData,0,d,3,9);os.write(d,0,12);os.flush();}catch(Exception e){}}public void sendUserListData(byte[] ud){byte[] hh=new byte[12];hh[0]=6;System.arraycopy(Convert.shortToBytes((short)ud.length),0,hh,1,2);sendData(hh,ud,ud.length);}public void sendData(byte[] hh,byte[] dd,int ln){try{os.write(hh);os.write(dd,0,ln);}catch(Exception e){}}}8、数据接收类(保证读取TCP字节数组数据长度正确)package sunstudio.util;import java.io.*;public class HttpInputStream extends InputStream{InputStream is=null;public HttpInputStream(InputStream is1){is=is1;}public int read() throws IOException{return is.read();}public String readLine() throws IOException{ByteArrayOutputStream b=new ByteArrayOutputStream();int c;while((c=read())!=-1){if(c==10)break;else b.write(c);}if(c==-1)return null;if(b.size()==1){if(b.toByteArray()[0]==13)return "";}return new String(b.toByteArray(),0,b.size()-1);}public static void readBytes(InputStream inputStream,int length,byte[] data) throws IOException{if(length==0)return;int n=0;int read=0;do{read=inputStream.read(data,n,length-n);n+=read;if(n==-1)throw new IOException("网络连接异常断开,读取数据异常");}while(n |
| (转载文章请保留出处:北天JAVA技术网(www.java114.com)) |
| |
| 更多精彩文章: |
| 谈谈TCP和UDP的一些简单应用 |
| 使用Java控制UDP协议 |
| JXTA开发以内容为中心的聊天软件项目 |
| 小弟最近从网站上下了一个JICQ 可是不知道怎么回事 |
| 一个Socket服务的例子! 请高手指点无法捕捉的输出如何修改? |
| Java socket编程入门[1] |
| |
| 最近评论: |
|
|
| 鍥炲 |
|
|
|
| 那个雨天的想法! |
| wow gold,wow power leveling.wow power leveling,wow power leveling,
max(5517) |
|
|
| 如果真的有来生! |
| 四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游,
max(8395) |
|
|
| 如果真的有来生! |
| 四川旅游,九寨沟旅游,稻城亚丁旅游,四姑娘山旅游,海螺沟旅游,西藏旅游,
max(6395) |
|
|
| 轻轻走过你的窗前! |
| world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold, max(638) |
|
|
| 轻轻走过你的窗前! |
| world of warcraft gold,cheap world of warcraft gold,warcraft gold,world of warcraft gold,cheap world of warcraft gold,warcraft gold max(5259) |
|
|
| 不在的哪天! |
| final fantasy xi gil,final fantasy xi gil,final fantasy xi gil,final fantasy xi gil,
max(9012) |
|
|
| 昨夜的狂想曲! |
| wow gold,WoW Gold,world of warcraft gold,WoW Gold, max(8955) |
|
|
| 没有情人的情人节! |
| wow gold,wow power leveling.wow power leveling,wow power leveling,
max(7769) |
|
|
| 回复:如何用Java实现网络中国象棋室(二) |
| power leveling
world of warcraft gold
power leveling wow
wow gold
buy wow gold
wow power leveling
guild wars gold
Maple Mesos
guild wars money
cheap Maple Story Mesos
buy Maple Meso
gw money
cheap guild wars money
Maple Story Meso
cheap MapleStory Mesos
runescape money
runescape coin
runescape gold
runescape power leveling
buy runescape gold
runescape gold
runescape gp |
|
|
| |
| 免责声明:该文章由网友发表,如果对您造成侵权,请联系站长。 |
|