簡單伺服器與客戶端互動(例項:簡單揹包)
//伺服器端程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using LitJson;
namespace Package
{
class Server
public TcpListener tcpListener;//宣告公眾變數,以方便在別的方法中進行呼叫
public TcpClient tcpClient;
public List<TcpClient> tcpClients = new List<TcpClient>();//客戶端的集合,多個客戶端連線時,儲存進集合,本篇中未使用
public List<Data> datas = new List<Data>();//封裝傳送接收資料的類Data
public List<UserModel> users = new List<UserModel>();//同理
public List<Goods> goods = new List<Goods>();
public List<Stores> stores = new List<Stores>();
{static void Main(string[] args)
{
Server server = new Server();//例項化自身,呼叫自身
server.Start();
}
void Start()
{
tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 5050);//繫結Ip,埠
//"127.0.0.1" 通用自身IP
tcpListener.Start(); //啟動 tcpListener
Thread thread = new Thread(AcceptClient);//開啟分執行緒,防止程序卡死
thread.Start();
}
void AcceptClient()
{
try
{
while (true)//一直在迴圈判斷狀態
{
if (tcpListener.Pending())//判定是否有客戶端連線
{
//獲取本地json檔案,這三個可以封裝成一個方法,我沒封裝
tcpClient = tcpListener.AcceptTcpClient();
if (GetData()!=null)
{
users = JsonMapper.ToObject<List<UserModel>>(GetData());
}
if (GetDataGoods() != null)
{
goods = JsonMapper.ToObject<List<Goods>>(GetDataGoods());
}
if (GetDataStores() != null)
{
stores = JsonMapper.ToObject<List<Stores>>(GetDataStores());
}
Console.WriteLine("客戶端接入");
Data data = new Data(tcpClient,this);
datas.Add(data);//當有客戶端接上,先例項化Data類,即接收,傳送訊息的類,再把類新增到集合中
//tcpClients.Add(tcpClient);
}
Thread.Sleep(100);//執行緒休眠0.1秒
}
}
catch (Exception e)
{
Console.WriteLine(e);//丟擲異常,列印輸出
}
}
//獲取本地json檔案
string GetData()
{
string filePath = AppDomain.CurrentDomain.BaseDirectory + @"/Users.json";
if (!File.Exists(filePath))
{
return null;
}
return File.ReadAllText(filePath);
}
string GetDataGoods()
{
string filePath = AppDomain.CurrentDomain.BaseDirectory + @"/Goods.json";
if (!File.Exists(filePath))
{
return null;
}
return File.ReadAllText(filePath);
}
string GetDataStores()
{
string filePath = AppDomain.CurrentDomain.BaseDirectory + @"/Stores.json";
if (!File.Exists(filePath))
{
return null;
}
return File.ReadAllText(filePath);
}
}
}
Data類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using LitJson;
using System.IO;
namespace Package
{
//宣告兩個最基本的類,Request和Respones,所有與客戶端資料的互動都是通過這兩個類
public class Request
{
public string Type;
public string Data;
public int Code;
}
public class Respones
{
public string Type;
public string Data;
}
//一個有關於使用者的模型
public class UserModel
{
public string Name;//名字
public string PassWord;//密碼
public int HP;//血量
public int Attack;//攻擊力
public int Speed;//速度
public int[] Goods;//揹包不同藥品的數量的陣列
}
//登入請求
public class login
{
public string Name;
public string Password;
}
//藥品模型
public class Goods
{
public string Name;
public int Id;
public string Nature;
public int Value;
public string Icon;
public string Des;
}
//商店商品模型
public class Stores
{
public string Name;
public int Id;
public string Nature;
public int Value;
public string Icon;
public string Des;
}
class Data
{
public TcpClient tcpClient;
public Server server;
public NetworkStream stream;
public Thread thread;
public Data(TcpClient _tcpClient,Server _server)
{
tcpClient = _tcpClient;
server = _server;
thread = new Thread(ReceMsg);//分執行緒
thread.Start();
}
//接收訊息,先接受訊息,對訊息進行一定的處理後,再呼叫傳送訊息的方法
void ReceMsg()
{
try
{
stream = tcpClient.GetStream();
byte[] ReceBuffer = new byte[7000];
while (tcpClient.Connected)
{
int length = stream.Read(ReceBuffer, 0, ReceBuffer.Length);
string str = Encoding.UTF8.GetString(ReceBuffer, 0, length);
Respones info = JsonMapper.ToObject<Respones>(str);//接受到的訊息都轉化為Respones 類
Midtranslate(info);
}
}
catch (Exception e)
{
Console.WriteLine(e);
Stop();
}
}
//處理接收到的訊息
void Midtranslate(Respones res)
{
Request req = new Request();//定義傳送訊息的類,例項化內容
req.Type = res.Type;
switch (res.Type)
{
case "Rigister"://接收到註冊請求
bool isseek = false;
//接收到客戶端傳來的內容,先轉化為Respones 類,再把Respones 中的Data轉化為UserModel 進行處理
//在這裡UserModel 是使用者的基本資訊,把註冊成功的使用者儲存到伺服器中.
UserModel model = JsonMapper.ToObject<UserModel>(res.Data);
for (int i = 0; i < server.users.Count; i++)
{
if (model.Name == server.users[i].Name)
{
req.Data = "賬戶已存在!";
isseek = true;
break;
}
}
if (isseek == true)
{
req.Code = 0;
}
else
{
req.Data = "註冊成功";
req.Code = 1;
server.users.Add(model);//使用者資訊儲存到集合中
server.users.Sort(delegate (UserModel x, UserModel y)//根據戰鬥力排序
{
return y.Attack.CompareTo(x.Attack);
});
SaveDataUser(JsonMapper.ToJson(server.users));//伺服器把使用者資訊的集合儲存到本地
}
sendMsg(req);//傳送訊息
break;
case "Login":
Console.WriteLine("login接收");
bool isexist = false;
login user1 = JsonMapper.ToObject<login>(res.Data);
for (int i = 0; i < server.users.Count; i++)
{
if (user1.Name == server.users[i].Name&& user1.Password == server.users[i].PassWord)
{
isexist = true;
req.Data = JsonMapper.ToJson(server.users[i]);
req.Code = 1;
break;
}
}
if (isexist == false)
{
req.Data = "使用者名稱不存在!";
req.Code = 0;
}
sendMsg(req);
break;
case "Goods":
req.Data = JsonMapper.ToJson(server.goods);
req.Code = 1;
sendMsg(req);
break;
case "Stores":
req.Data = JsonMapper.ToJson(server.stores);
req.Code = 1;
sendMsg(req);
break;
case "Ranking":
req.Data = JsonMapper.ToJson(server.users);
req.Code = 1;
sendMsg(req);
break;
case "Save":
bool isrepetition = false;
UserModel user2 = JsonMapper.ToObject<UserModel>(res.Data);
for (int i = 0; i < server.users.Count; i++)
{
if (server.users[i].Name == user2.Name)
{
server.users[i] = user2;
req.Code = 1;
res.Data = "";
isrepetition = true;
break;
}
}
if (isrepetition == false)
{
req.Code = 0;
res.Data = "";
}
SaveDataUser(JsonMapper.ToJson(server.users));
sendMsg(req);
break;
}
}
void Stop()
{
Console.WriteLine(tcpClient.Client.RemoteEndPoint + "退出");
tcpClient.Client.Close();
thread.Interrupt();
}
//傳送訊息
void sendMsg(Request req)
{
try
{
byte[] SendBuffer = Encoding.UTF8.GetBytes(JsonMapper.ToJson(req));
stream.Write(SendBuffer, 0, SendBuffer.Length);
}
catch (Exception e)
{
Console.WriteLine(e);
Stop();
}
}
//儲存至本地的方法
void SaveDataUser(string data)
{
string filePath = AppDomain.CurrentDomain.BaseDirectory + @"/Users.json";
File.WriteAllText(filePath, data);
}
}
}
這是有關於伺服器端簡單構架,只能是實現一些簡單的功能,處理的請求也只有幾種,客戶端的程式碼在下一篇中會放出.