c#网编实验五--WCF和TCP消息通信实验

分别编写服务端和客户端程序,利用基于WCF的TCP技术,实现在线聊天功能,完成在线用户列表管理,消息发送、接收的功能。

在同一个解决方案中,分别编写服务端程序和客户端程序,利用TCP实现简单的群聊功能。

c#网编实验五--WCF和TCP消息通信实验_第1张图片

c#网编实验五--WCF和TCP消息通信实验_第2张图片 

c#网编实验五--WCF和TCP消息通信实验_第3张图片 

具体要求如下:
(1)服务端程序选择【WCF服务库】模板,客户端程序选择【WPF应用程序】模板。
(2)客户端与服务端连接成功后,通过服务端获取已经在线的用户,并将其显示在客户端的在线用户列表中。
(3)不论哪个用户发送聊天消息,其他所有用户都能看到该消息。
(4)当某个用户退出后,在线用户列表中自动移除该用户。
 

重点:

(1)掌握TCP协议下WCF服务应用程序构建方法。
(2)掌握客户端和服务端通信接口设计方法。
(3)掌握协定的设计及实现方法。
(4)掌握双工通信的设计及实现方法。
(5)熟悉WCF和TCP的相关绑定设置。
难点:

(1)掌握客户端和服务端通信接口设计方法。
(2)掌握协定的设计及实现方法。
(3)掌握双工通信的设计及实现方法。
(4)熟悉WCF和TCP的相关绑定设置。
 

客户端

MainWindow.xaml


    
        

 c#网编实验五--WCF和TCP消息通信实验_第4张图片

 

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ChatClient
{
    /// 
    /// MainWindow.xaml 的交互逻辑
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btn1_Click(object sender, RoutedEventArgs e)
        {
            StartWindow("西西皮", 50, 300);
            StartWindow("瓜瓜糖", 600, 300);
        }

        private void StartWindow(string userName, int left, int top)
        {
            ClientWindow w = new ClientWindow();
            w.Left = left;
            w.Top = top;
            w.UserName = userName;
            w.Owner = this;
            w.Closed += (sender, e) => this.Activate();
            w.Show();
        }

        private void btn2_Click(object sender, RoutedEventArgs e)
        {
            ClientWindow w = new ClientWindow();
            w.Owner = this;
            w.Closed += (sendObj, args) => this.Activate();
            w.Show();
        }
    }
}

ClientWindow.xaml


    
        
            
            
        
        
            
            
            

 

c#网编实验五--WCF和TCP消息通信实验_第5张图片 

ClientWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ChatClient.ChatServiceReference;

namespace ChatClient
{
    /// 
    /// ClientWindow.xaml 的交互逻辑
    /// 
    public partial class ClientWindow : Window, IChatServiceCallback
    {
        public ClientWindow()
        {
            InitializeComponent();
            this.Closing += ClientWindow_Closing;
            dockPanel1.Visibility = System.Windows.Visibility.Hidden;
        }

        public string UserName
        {
            get { return textBoxUserName.Text; }
            set { textBoxUserName.Text = value; }
        }
        private ChatServiceClient client;

        void ClientWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (client != null)
            {
                client.Logout(UserName); //退出
                client.Close();
            }
        }

        private void AddMessage(string str)
        {
            TextBlock t = new TextBlock();
            t.Text = str;
            t.Foreground = Brushes.Blue;
            listBoxMessage.Items.Add(t);
        }

        //单击登录按钮引发的事件
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;
            UserName = textBoxUserName.Text;
            InstanceContext context = new InstanceContext(this);
            client = new ChatServiceReference.ChatServiceClient(context);
            try
            {
                client.Login(textBoxUserName.Text);
                btnLogin.IsEnabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show("与服务端连接失败:" + ex.Message);
                return;
            }
            this.Cursor = Cursors.Arrow;
        }

        //单击发送按钮引发的事件
        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            client.Talk(UserName, textBoxTalk.Text);
            textBoxTalk.Text = "";
        }

        //在文本框中输入对话后按回车键时引发的事件
        private void textBoxTalk_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                client.Talk(UserName, textBoxTalk.Text);
                textBoxTalk.Text = "";
            }
        }

        #region 实现IRndGameServiceCallback接口
        /// 有用户登录
        public void ShowLogin(string loginUserName)
        {
            if (loginUserName == UserName)
            {
                dockPanel1.Visibility = System.Windows.Visibility.Visible;
            }
            listBoxOnLine.Items.Add(loginUserName);
        }

        /// 其他用户退出
        public void ShowLogout(string userName)
        {
            listBoxOnLine.Items.Remove(userName);
        }

        public void ShowTalk(string userName, string message)
        {
            AddMessage(string.Format("[{0}]说:{1}", userName, message));
        }

        public void InitUsersInfo(string UsersInfo)
        {
            if (UsersInfo.Length == 0) return;
            string[] users=UsersInfo.Split('、');
            for (int i = 0; i < users.Length; i++)
            {
                listBoxOnLine.Items.Add(users[i]);
            }
        }
        #endregion
    }
}

服务端

IChatService.cs

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

namespace ChatServer
{
    //需要服务端实现的协定
    [ServiceContract(Namespace = "WcfChatExample", CallbackContract = typeof(IChatServiceCallback))]
    public interface IChatService
    {
        [OperationContract(IsOneWay = true)]
        void Login(string userName);

        [OperationContract(IsOneWay = true)]
        void Logout(string userName);

        [OperationContract(IsOneWay = true)]
        void Talk(string userName, string message);
    }

    //需要客户端实现的接口
    public interface IChatServiceCallback
    {
        [OperationContract(IsOneWay = true)]
        void ShowLogin(string loginUserName);

        [OperationContract(IsOneWay = true)]
        void ShowLogout(string userName);

        [OperationContract(IsOneWay = true)]
        void ShowTalk(string userName, string message);

        [OperationContract(IsOneWay = true)]
        void InitUsersInfo(string UsersInfo);
    }
}

 

 

 ChatService.cs

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

namespace ChatServer
{
    public class ChatService : IChatService
    {
        /// 
        /// 用户退出。参数:登录者用户名
        /// 
        public void Login(string userName)
        {
            OperationContext context = OperationContext.Current;
            IChatServiceCallback callback = context.GetCallbackChannel();
            User newUser = new User(userName, callback);
            string str = "";
            for (int i = 0; i < CC.Users.Count; i++)
            {
               str += CC.Users[i].UserName + "、";
            }
            newUser.callback.InitUsersInfo(str.TrimEnd('、'));
            CC.Users.Add(newUser);
            foreach (var user in CC.Users)
            {
                user.callback.ShowLogin(userName);
            }
        }

        /// 
        /// 用户退出。参数:退出者用户名
        /// 
        public void Logout(string userName)
        {
            User logoutUser = CC.GetUser(userName);
            CC.Users.Remove(logoutUser);
            logoutUser = null; //将其设置为null后,WCF会自动关闭该客户端
            foreach (var user in CC.Users)
            {
                user.callback.ShowLogout(userName);
            }
        }

        /// 
        /// 客户端发来的对话信息。参数:发送者用户名,对话内容
        /// 
        public void Talk(string userName, string message)
        {
            User user = CC.GetUser(userName);
            foreach (var v in CC.Users)
            {
                v.callback.ShowTalk(userName, message);
            }
        }
    }
}

User.cs

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

namespace ChatServer
{
    public class User
    {
        public string UserName { get; set; }
        public readonly IChatServiceCallback callback;

        public User(string userName, IChatServiceCallback callback)
        {
            this.UserName = userName;
            this.callback = callback;
        }
    }
}

 

CC.cs

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

namespace ChatServer
{
    public class CC
    {
        //连接的用户,每个用户都对应一个ChatService线程
        public static List Users { get; set; }

        static CC()
        {
            Users = new List();
        }

        public static User GetUser(string userName)
        {
            User user = null;
            foreach (var v in Users)
            {
                if (v.UserName == userName)
                {
                    user = v;
                    break;
                }
            }
            return user;
        }
    }
}

你可能感兴趣的:(网络应用编程,tcp/ip,网络,服务器,c#,wpf,网络编程)