📄 zgxq.java
字号:
package sunstudio.chess.event;
import java.util.*;
import java.net.*;
import java.io.*;
import sunstudio.util.*;
import sunstudio.*;
public class ChessLogin implements Runnable{ServerSocket ss=null;
boolean isrunning=true;
Vector listeners=new Vector();
int guestid=0;
public ChessLogin(ChessServer s)
{
ss=s.ss;
addLoginListener(s);
new Thread(this).start();
}
public void run()
{
while(isrunning)
{
try
{
Socket socket=ss.accept();
String un=chkLogin(socket.getInputStream());
if(un!=null)notifyListener(guestid++,un,socket);
}
catch(IOException e){}
}
}
public void addLoginListener(LoginListener l){
listeners.addElement(l);
}
void notifyListener(int userid,String username,Socket sock){
LoginEvent evt=new LoginEvent(userid,username,sock);
for(Enumeration enu=listeners.elements();enu.hasMoreElements();)
{
((LoginListener)enu.nextElement()).onLoginEvent(evt);
}
}
public String chkLogin(InputStream is)throws IOException {
byte[] head=new byte[12]; HttpInputStream.readBytes(is,12,head);
int cmdtype=head[0];int totalsize=Convert.byteToShort(head [1],head[2]);
if(totalsize==0)
return null;
byte[] data=new byte[totalsize];
HttpInputStream.readBytes(is,totalsize,data);
//System.out.print("type="+cmdtype+",totalsize="+totalsize+",username="+parseLoginDa ta(data));
return parseLoginData(data);
}
public String parseLoginData(byte[] d)
{
return new String(d);
}
public static int byteToInt(byte j,byte k,byte m,byte n)
{ int a =j&0xff;
int b =k&0xff;
int c =m&0xff;
int d =n&0xff;
return (d<<24|c<<16|b<<8|a);
}
}//////////////////定义登录连接事件类
package sunstudio.chess.event;
import java.net.*;
public class LoginEvent{public int userID;public String username;
public Socket socket;
public LoginEvent(int userID,String username,Socket sock){
this.userID=userID;
this.username=username;this.socket=sock;
}
}//////////////////登录监听接口
package sunstudio.chess.event;
public interface LoginListener{public void onLoginEvent(LoginEvent evt);
}
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;i19)
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.element ();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<>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -