程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 如何用Java實現網絡中國象棋室(二)

如何用Java實現網絡中國象棋室(二)

編輯:關於JAVA

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

}

}

(待續。。。)如有問題請和我聯系[[email protected]]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved