【C#大作业】你画我猜——服务端实现

1、App.config配置文件

##App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- 部署服务库项目时,必须将配置文件的内容添加到
 主机的 app.config 文件中。System.Configuration 不支持库的配置文件。 -->
  <system.serviceModel>
    <services>
      <service name="Service.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- 除非完全限定,否则地址相对于上面提供的基址-->
        <endpoint address="net.tcp://localhost:51888/Service1/" binding="netTcpBinding" contract="Service.IService1">
          <!-- 
              部署时,应删除或替换下列标识元素,以反映
             用来运行所部署服务的标识。删除之后,WCF 将
              自动推断相应标识。
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 -->
        <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
          以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

2、IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Service
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    [ServiceContract(Namespace = "IService",
        CallbackContract = typeof(IService1Callback))]
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    public interface IService1
    {

        // TODO: 在此添加您的服务操作
        //[OperationContract(IsOneWay = true)]
        //void InitRooms();

        [OperationContract(IsOneWay = true)]
        void Login(string userName); //登录系统

        [OperationContract(IsOneWay = true)]
        void Logout(string userName); //登出系统

        [OperationContract(IsOneWay = true)]
        void Talk(string userName, string message); //大厅聊天

        [OperationContract(IsOneWay = true)]
        void InRoom(string username, string roomname); //进入游戏房间

        [OperationContract(IsOneWay = true)]
        void Room_Talk(string userName, string message); //房间内聊天

        [OperationContract(IsOneWay = true)]
        void sendink(string username, string ink); //传送笔迹

        [OperationContract(IsOneWay = true)]
        void Guess_talk(string username, string message); //猜测框消息

        [OperationContract(IsOneWay = true)]
        void Gusee_win(string username); //猜测正确

        [OperationContract(IsOneWay = true)]
        void change_hua(string username); //改变画题人

        [OperationContract(IsOneWay = true)]
        void Refersh_Timu(string username); //刷新题目

        [OperationContract(IsOneWay = true)]
        void RoomOut(string username); //用户退出房间
    }


    public interface IService1Callback
    {
        [OperationContract(IsOneWay = true)]
        void ShowLogin(string loginUserName, int[] roomcount); //显示新用户登录游戏,进入大厅

        [OperationContract(IsOneWay = true)]
        void ShowLogout(string userName); //显示用户退出游戏

        [OperationContract(IsOneWay = true)]
        void ShowTalk(string userName, string message); //在大厅发消息显示消息内容

        [OperationContract(IsOneWay = true)]
        void InitRoomUsersInfo(string RoomUsersInfo, string ink, bool hua_or_cai, string timu); //初始化房间玩家列表

        [OperationContract(IsOneWay = true)]
        void ShowInRoom(string username); //显示用户进入房间

        [OperationContract(IsOneWay = true)]
        void ShowOutRoom(string userName); //显示用户退出房间

        [OperationContract(IsOneWay = true)]
        void Showlabel(string labelname, int roomusercount); //大厅界面显示四个房间的人数

        [OperationContract(IsOneWay = true)]
        void Show_Room_Talk(string userName, string message); //显示在房间里聊天的消息
        [OperationContract(IsOneWay = true)]
        void Show_Room_Talk_error(string message); //显示在房间里聊天的消息

        [OperationContract(IsOneWay = true)]
        void Show_Guess_Talk(string userName, string message, string daan); //显示猜测聊天框中的聊天消息

        [OperationContract(IsOneWay = true)]
        void Showink(string ink); //显示墨迹信息

        [OperationContract(IsOneWay = true)]
        void Show_Guess_win(string username); //显示用户猜中

        [OperationContract(IsOneWay = true)]
        void Show_Refersh_Timu(string username, string Timu); //刷新题目后,在各个玩家界面显示

        [OperationContract(IsOneWay = true)]
        void Show_Cannot_login();//提示用户不能登录

        [OperationContract(IsOneWay = true)]
        void InitNewchutiren(string timu);//初始化新的出题人界面

        [OperationContract(IsOneWay = true)]
        void change_hua_or_cai(bool hua, string username);//改变画题人和猜题人
    }
}

3、游戏房间:Room.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    class Room
    {
        public string RoomName { get; set; } //游戏房间名
        public readonly IService1Callback callback; 
        public List<Users> game_user { get; set; } //房间玩家列表
        public string Timu; //房间的游戏题目
        public string ink; //房间的墨迹信息
        public Room(string RoomName, IService1Callback callback)//构造函数
        {
            this.RoomName = RoomName;
            this.callback = callback;
            this.game_user = new List<Users>();
            string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
            Timu = refer_timu(str_1 + "\\tiku.txt");
            ink = "";
        }

        public string refer_timu(string path)//刷新题库
        {
            string[] line = File.ReadAllLines(path);
            Random ro = new Random();
            int co = ro.Next(0, line.Length);
            Timu = line[co];
            return Timu;
        }
    }
}

4、房间列表类:RoomInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    class RoomInfo
    {
        public static List<Room> Rooms { get; set; } //系统房间列表

        static RoomInfo()
        {
            Rooms = new List<Room>();
            for (int i = 1; i <= 4; i++)//初始化四个房间
            {
                string roomname = "room" + i.ToString();
                OperationContext context1 = OperationContext.Current;
                IService1Callback callback1 = context1.GetCallbackChannel<IService1Callback>();
                Room room = new Room(roomname, callback1);
                Rooms.Add(room);
            }
        } //构造函数

        public static Room GetRoom(string roomname)
        {
            Room room = null;
            foreach (var v in Rooms)
            {
                if (v.RoomName == roomname)
                {
                    room = v;
                    break;
                }
            }
            return room;
        }//获取对应的房间
    }
}

5、Service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Service
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
    public class Service1 : IService1
    {
        public void Login(string userName) //登录系统
        {
            //在线用户列表中加入该用户
            OperationContext context = OperationContext.Current;
            IService1Callback callback = context.GetCallbackChannel<IService1Callback>();
            Users newUser = new Users(userName, callback);

            //判断是否存在该用户
            foreach (var v in UserInfo.Users)
            {
                if (v.UserName == userName)
                {
                    newUser.callback.Show_Cannot_login();
                    return;
                }
            }

            //如果不存在将该用户加入房间列表
            UserInfo.Users.Add(newUser);

            //获得房间人数,显示用户登录,并初始化该用户界面
            int[] a = new int[5];
            for (int i = 0; i < 4; i++)
            {
                a[i] = RoomInfo.Rooms[i].game_user.Count();
            }
            foreach (var user in UserInfo.Users)
            {
                user.callback.ShowLogin(userName, a);
            }
        }

        public void Logout(string userName) //登出系统
        {
            //在线用户列表中移除该用户
            Users logoutUser = UserInfo.GetUser(userName);

            //如果该用户在房间中,则从该房间玩家列表中移除该用户
            if (logoutUser.inRoom) 
            {
                RoomOut(userName);
            }
            //从在线玩家列表移除该用户
            UserInfo.Users.Remove(logoutUser);
            logoutUser = null;

            //展示用户退出游戏
            foreach (var user in UserInfo.Users)
            {
                user.callback.ShowLogout(userName);
            }
        }

        public void Talk(string userName, string message) //大厅聊天
        {
            //向所有用户显示聊天消息
            foreach (var v in UserInfo.Users)
            {
                v.callback.ShowTalk(userName, message);
            }
        }

        public bool Filter(string timu, string message) //画图人不能说出与答案有关的话
        {
            return message.Contains(timu);
        }

        public void Room_Talk(string userName, string message) //房间内聊天
        {
            //获得相应的用户和房间
            Users user = UserInfo.GetUser(userName);
            Room room = RoomInfo.GetRoom(user.RoomName);

            //过滤
            if (Filter(room.Timu, message) && user.hua_or_cai)
            {
                user.callback.Show_Room_Talk_error("可能包含答案信息,发送失败。");
                return;
            }

            //向房间内所有用户显示消息
            foreach (var v in room.game_user)
            {
                v.callback.Show_Room_Talk(userName, message);
            }
        }

        public void Guess_talk(string username, string message) //猜测框消息
        {
            //同上
            Users user = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(user.RoomName);
            foreach (var v in room.game_user)
            {
                v.callback.Show_Guess_Talk(username, message, room.Timu);
            }
        }

        public void InRoom(string username, string roomname) //进入游戏房间
        {
            //获取相应的用户和房间
            Users inroomuser = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(roomname);

            //如果是房间的第一个人,则这个人画画,以后进来的人猜
            if (room.game_user.Count == 0) 
                inroomuser.hua_or_cai = true;
            else
                inroomuser.hua_or_cai = false;

            inroomuser.inRoom = true;
            inroomuser.RoomName = roomname;

            //初始化新进来玩家的界面
            //初始化新进来的玩家的玩家列表界面、题目和画板墨迹
            string str = "";
            for (int i = 0; i < room.game_user.Count; i++)
            {
                str += room.game_user[i].UserName + "、";
            }
            if (room.game_user.Count == 0)
                inroomuser.callback.InitRoomUsersInfo(str.TrimEnd('、'), null, inroomuser.hua_or_cai, room.Timu);
            else
                inroomuser.callback.InitRoomUsersInfo(str.TrimEnd('、'), room.ink, inroomuser.hua_or_cai, room.Timu);

            //该房间的玩家列表加入该玩家
            room.game_user.Add(inroomuser);
            //获得用户进入房间对应的人数标签名字
            string labelname = roomname + "_user_count"; 
            //展示用户进入游戏房间
            foreach (var user in room.game_user)
            {
                user.callback.ShowInRoom(username);
            }
            //更改所有用户大厅的房间人数标签
            foreach (var user in UserInfo.Users)
            {
                user.callback.Showlabel(labelname, room.game_user.Count());
            }
        }

        public void sendink(string username, string ink) //传送笔迹
        {
            Users user = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(user.RoomName);
            //设置房间的墨迹信息,同时向所有玩家同步
            room.ink = ink;
            foreach (var v in room.game_user)
            {
                v.callback.Showink(room.ink);
            }
        }

        public void Gusee_win(string username) //猜测正确
        {
            Users user = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(user.RoomName);

            //房间墨迹清空。向所有用户展示某用户猜对
            room.ink = null;
            foreach (var v in room.game_user)
            {
                v.callback.Show_Guess_win(username);
            }
            //猜对的人成为画题人,其余人猜题
            change_hua(username);
        }

        public void Refersh_Timu(string username) //刷新题目
        {
            Users user = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(user.RoomName);

            //获得题库地址刷新题目,并清空墨迹
            string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
            room.Timu = room.refer_timu(str_1 + "\\tiku.txt");
            room.ink = "";
            foreach (var v in room.game_user)
            {
                v.callback.Show_Refersh_Timu(username, room.Timu);
                v.callback.Showink(room.ink);
            }
        }

        public void RoomOut(string username)
        {
            Users logoutUser = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(logoutUser.RoomName);
            logoutUser.inRoom = false;
            logoutUser.RoomName = "";
            //如果玩家不是画题人,正常退出。否则在猜题人中选择一个作为新的画题人。
            if (!logoutUser.hua_or_cai)
            {
                logoutUser.callback.ShowOutRoom(username);
                foreach (var user in room.game_user)
                {
                    user.callback.ShowOutRoom(username);
                }
                room.game_user.Remove(logoutUser);
            }
            else
            {
                logoutUser.hua_or_cai = false;
                foreach (var item in room.game_user)
                {
                    if (item.UserName != logoutUser.UserName)
                    {
                        item.hua_or_cai = true;
                        item.callback.InitNewchutiren(room.Timu);
                        break;
                    }
                }

                room.ink = "";
                foreach (var v in room.game_user)
                    v.callback.Showink(room.ink);

                foreach (var user in room.game_user)
                {
                    user.callback.ShowOutRoom(username);
                }
                room.game_user.Remove(logoutUser);
            }
            //更新大厅的房间信息
            foreach (var v in UserInfo.Users)
            {
                v.callback.Showlabel(room.RoomName + "_user_count", room.game_user.Count());
            }
            //如果房间剩余人数为0,清空墨迹信息
            if (room.game_user.Count() == 0)
                room.ink = "";
        } //用户退出房间

        public void change_hua(string username) //改变画题人
        {
            Users old_User = null;
            foreach (var item in UserInfo.Users)
            {
                if (item.hua_or_cai)
                {
                    old_User = item;
                    break;
                }
            }
            Users new_User = UserInfo.GetUser(username);
            Room room = RoomInfo.GetRoom(new_User.RoomName);
            old_User.hua_or_cai = false;
            new_User.hua_or_cai = true;
            old_User.callback.change_hua_or_cai(false, new_User.UserName);
            new_User.callback.change_hua_or_cai(true, new_User.UserName);
        }
    }
}

6、用户列表:UserInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    class UserInfo
    {
        public static List<Users> Users { get; set; } //在线用户列表

        static UserInfo()
        {
            Users = new List<Users>();
        }//构造函数

        public static Users GetUser(string userName)
        {
            Users user = null;
            foreach (var v in Users)
            {
                if (v.UserName == userName)
                {
                    user = v;
                    break;
                }
            }
            return user;
        } //获得用户
    }
}

7、用户类:Users.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    class Users
    {
        public string UserName { get; set; } //用户名
        public readonly IService1Callback callback;
        public bool hua_or_cai; //画题人或者出题人
        public bool inRoom; //用户是不是在房间内
        public string RoomName; //用户如果在房间内,则对应的额房间名

        public Users(string userName, IService1Callback callback) //构造函数
        {
            this.UserName = userName;
            this.callback = callback;
            hua_or_cai = false;
            inRoom = false;
            RoomName = "";
        }
    }
}

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实现一个 C# 的 FTPS 服务端,可以使用 .NET Framework 提供的 FtpListener 类来监听客户端连接请求和处理客户端的操作。 以下是一个简单的示例: ```csharp using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; class FtpsServer { private readonly TcpListener _listener; private readonly X509Certificate2 _certificate; private readonly bool _requireClientCertificate; public FtpsServer(IPAddress address, int port, X509Certificate2 certificate, bool requireClientCertificate) { _listener = new TcpListener(address, port); _certificate = certificate; _requireClientCertificate = requireClientCertificate; } public async Task StartAsync() { _listener.Start(); while (true) { TcpClient client = await _listener.AcceptTcpClientAsync(); await Task.Run(() => HandleClientAsync(client)); } } private async Task HandleClientAsync(TcpClient client) { SslStream sslStream = null; try { sslStream = new SslStream(client.GetStream(), false); await sslStream.AuthenticateAsServerAsync(_certificate, _requireClientCertificate, SslProtocols.Tls12, false); // 在此处处理客户端的 FTPS 请求和操作 } catch (AuthenticationException e) { Console.WriteLine($"Authentication failed: {e.Message}"); } catch (IOException e) { Console.WriteLine($"I/O error: {e.Message}"); } finally { sslStream?.Dispose(); client.Dispose(); } } } ``` 在 HandleClientAsync 方法中,可以使用 sslStream 对象来读取客户端发送的 FTPS 命令和数据,发送响应数据。 需要注意的是,客户端连接成功后,需要进行 SSL/TLS 握手协商,会话密钥的协商需要使用证书。如果客户端在连接时没有提供证书,可以通过设置 requireClientCertificate 参数为 false,来允许匿名连接。 示例代码中的 X509Certificate2 对象可以通过以下方式创建: ```csharp X509Certificate2 certificate = new X509Certificate2("mycert.pfx", "password"); ``` 其中,mycert.pfx 是证书文件的路径,password 是证书文件的密码。 以上是一个简单的实现,实际情况中还需要考虑更多细节,如用户认证、文件传输等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值