接上次的五子棋案例,此次实现的是在局域网中的简单匹配对战,即当一个玩家点击准备对战时,连接服务器并开启一个线程监听服务器反馈回来的消息,然后解析消息,执行对应操作。
服务器实现简单匹配思路:
(1)收到玩家1的准备信息,把玩家1加入到准备队列
(2)收到玩家2的准备信息,把玩家2加入到准备队列
(3)当准备队列有两个人时,把这两个ip的玩家合成一个在玩局加入到正在游戏队列,同时从准备队列中移除这两个玩家
(4)当服务器收到玩家信息时去查询正在游戏队列中包含收到玩家信息的ip,把对应消息给这两个ip返回
(5)客户端对服务器返回的消息解析,执行不同的操作
服务器端代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Net.Sockets;
usingSystem.Threading;
namespaceServer
{
classClient
{
privateSocketclientSocket;
privateThreadt;
privatebyte[]data=newbyte[1024];
publicstringipaddress;
publicClient(Sockets,stringipaddress)
{
clientSocket=s;
this.ipaddress=ipaddress;
t=newThread(ReceiveMessage);
t.Start();
}
privatevoidReceiveMessage()
{
while(true)
{
//在接收数据之前判断Socket连接是否断开
if(clientSocket.Poll(10,SelectMode.SelectRead))
{
clientSocket.Close();
break;
}
intlength=clientSocket.Receive(data);
stringmessage=Encoding.UTF8.GetString(data,0,length);
Console.WriteLine(message);
if(message.Contains("|||Ready|||")&&!message.Contains(":"))
{
if(!Program.ReadyClientList.Contains(message.Split('|')[0]))
{
Program.ReadyClientList.Add(message.Split('|')[0]);
}
}
if(Program.GameingClientList.Count>0)
{
foreach(vartempinProgram.GameingClientList)
{
if((message.Contains(temp.ip1)||message.Contains(temp.ip2)))
{
foreach(varTempinProgram.clientList)
{
if(Temp.ipaddress==temp.ip1||Temp.ipaddress==temp.ip2)
{
Temp.SendMessage(message);
}
}
if(message.Equals(temp.ip1 "|||GameOver|||")||message.Equals(temp.ip2 "|||GameOver|||"))
{
if(!Program.GameingCancelClientList.Contains(temp))
Program.GameingCancelClientList.Add(temp);
}
}
}
}
if(message.Contains("|||Cancel|||")&&!message.Contains(":"))
{
if(!Program.ReadyCancelClientList.Contains(message.Split('|')[0]))
Program.ReadyCancelClientList.Add(message.Split('|')[0]);
}
//清除不在准备游戏列表的对战组别
if(Program.ReadyCancelClientList.Count>0)
{
foreach(vartempinProgram.ReadyCancelClientList)
{
if(Program.ReadyClientList.Contains(temp))
{
Program.ReadyClientList.Remove(temp);
}
}
Program.ReadyCancelClientList.Clear();
}
//清除不在游戏列表的对战组别
if(Program.GameingCancelClientList.Count>0)
{
foreach(vartempinProgram.GameingCancelClientList)
{
if(Program.GameingClientList.Contains(temp))
{
Program.GameingClientList.Remove(temp);
}
}
Program.GameingCancelClientList.Clear();
}
//Console.WriteLine(Program.ReadyClientList.Count);
if(Program.ReadyClientList.Count>=2)
{
Program.MyStructmyStruct=newProgram.MyStruct();
myStruct.ip1=Program.ReadyClientList[0];
myStruct.ip2=Program.ReadyClientList[1];
Program.GameingClientList.Add(myStruct);
//Console.WriteLine(myStruct.ip1 "" myStruct.ip2);
//boolFirstRun=false;
//stringFristIp="";
foreach(vartempinProgram.clientList)
{
if(temp.ipaddress==myStruct.ip1)
{
//temp.SendMessage(temp.ipaddress "||加入房间" "\n" "IP为" temp.ipaddress "玩家先走!");
//temp.SendMessage("IP为" temp.ipaddress "玩家先走!");
//FristIp=temp.ipaddress;
//temp.SendMessage("|||CanDownChess|||");
temp.SendMessage(myStruct.ip2 "|||CanGame|||" "|||CanDownChess|||");
//FirstRun=true;
//temp.SendMessage(temp.ipaddress "加入房间");
//Console.WriteLine(temp.ipaddress);
}
if(temp.ipaddress==myStruct.ip2)
{
//temp.SendMessage(temp.ipaddress "||加入房间" "\n" "IP为" FristIp "玩家先走!");
temp.SendMessage(myStruct.ip1 "|||CanGame|||");
//temp.SendMessage("IP为" FristIp "玩家先走!");
//Console.WriteLine(temp.ipaddress);
}
}
Program.ReadyClientList.Clear();
}
Program.UpdateClientList();
//Console.WriteLine("当前连接人数为:" Program.clientList.Count);
}
}
publicvoidSendMessage(strings)
{
byte[]_data=Encoding.UTF8.GetBytes(s);
if(clientSocket.Connected)
{
try
{
clientSocket.Send(_data,_data.Length,SocketFlags.None);
}
catch(SocketException)
{
Console.WriteLine("套接字连接异常!");
throw;
}
}
}
publicboolConnected
{
get{returnclientSocket.Connected;}
}
}
}
主类Program
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Net.Sockets;
usingSystem.Net;
usingSystem.Threading.Tasks;
namespaceServer
{
classProgram
{
publicstructMyStruct
{
publicstringip1;
publicstringip2;
}
//所有连接过的客户端
publicstaticList<Client>clientList=newList<Client>();
//所有准备游戏的客户端
publicstaticList<string>ReadyClientList=newList<string>();
publicstaticList<string>ReadyCancelClientList=newList<string>();
//所有正在游戏的客户端组
publicstaticList<MyStruct>GameingClientList=newList<MyStruct>();
publicstaticList<MyStruct>GameingCancelClientList=newList<MyStruct>();
//检查从clientList清除没有连接服务器的客户端
publicstaticvoidUpdateClientList()
{
varnotConnectedList=newList<Client>();
foreach(varclientinclientList)
{
if(!client.Connected)
notConnectedList.Add(client);
}
//清除不连接的客户端
foreach(vartempinnotConnectedList)
{
clientList.Remove(temp);
}
notConnectedList.Clear();
}
staticstringipaddress="125.217.40.147";
staticvoidMain(string[]args)
{
Socketsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
socket.Bind(newIPEndPoint(IPAddress.Parse(ipaddress),7788));
socket.Listen(100);
Console.WriteLine("服务器正在运行......");
while(true)
{
SocketclientSocket=socket.Accept();
Console.WriteLine("IP为" ((IPEndPoint)clientSocket.RemoteEndPoint).Address "的客户端与服务器进行了连接!");
Clientclient=newClient(clientSocket,((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString());//把每个客户端通信的逻辑放到client类进行处理
client.SendMessage(client.ipaddress "|||WelcometotheworldofWzq|||");
clientList.Add(client);
}
}
}
}
客户端连接部分代码:
private string ipaddress = "125.217.40.147";
private int port = 7788;
public Socket clientSocket;
private Thread t;
private byte[]data=new byte[1024];
private string message = "";
public string IpAddress;
public void ConnectToServer()
{
clientSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
//跟服务器进行连接
try
{
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));
}
catch (Exception)
{
// show"很遗憾你没有连接上服务器,请点击准备游戏重新连接!";
throw;
}
//创建一个新的线程用于接收消息
if (clientSocket.Connected)
{
t = new Thread(Receivemessage);
t.Start();
}
}
void Receivemessage()
{
while (true)
{
if (clientSocket.Connected==false)
{
break;
}
int length = clientSocket.Receive(data);
message = Encoding.UTF8.GetString(data, 0, length);
}
}
public void Sendmessage(string s)
{
byte[] data = Encoding.UTF8.GetBytes(s);
clientSocket.Send(data);
}
准备游戏调用:Sendmessage(your IpAddress "|||Ready|||");
取消准备调用:Sendmessage(your IpAddress "|||Cancel|||");
下棋时调用:Sendmessage(your IpAddress "|||CanDownChess|||" "chess|||" 棋子x坐标 "|" 棋子y坐标);
悔棋时调用:Sendmessage(your IpAddress "|||Regred|||");
认输或者中途退出游戏时调用:Sendmessage(your IpAddress "|||Surrender|||");
这样,简单的匹配对战就完成了。当然,解析服务器返回消息并执行操作自己实现。这个只是个简单的思路,实际实现和服务器传递消息要做相应的请求接口,如果要长久保存数据,还要引入数据库的内容。
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved