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

这篇具有很好参考价值的文章主要介绍了c#网编实验五--WCF和TCP消息通信实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

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

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

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

重点:

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

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

客户端

MainWindow.xaml

<Window x:Class="ChatClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="主界面" Height="350" Width="525" WindowStartupLocation="CenterScreen">
    <StackPanel VerticalAlignment="Center">
        <Button Name="btn1" Margin="10" Width="170" Content="同时启动2个客户端(测试用)" Click="btn1_Click"/>
        <Button Name="btn2" Margin="10" Width="170" Content="只启动1个客户端(实际情况)" Click="btn2_Click"/>
    </StackPanel>
</Window>

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

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
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    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

<Window x:Class="ChatClient.ClientWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="群聊客户端" Height="300" Width="500">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="0" Background="Cornsilk" LastChildFill="False">
            <TextBlock Text="用户名:" DockPanel.Dock="Left" VerticalAlignment="Center"/>
            <TextBox Name="textBoxUserName" Text="西西" Width="100" VerticalAlignment="Center"/>
            <Button Name="btnLogin" Content="登录" Click="btnLogin_Click" DockPanel.Dock="Left" Padding="10 0 10 0" Margin="5"/>
        </DockPanel>
        <DockPanel Name="dockPanel1" Grid.Row="1">
            <Grid Width="60">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <TextBlock Text="在线用户" Grid.Row="0" Background="Blue" Foreground="White" TextAlignment="Center"/>
                <Grid Grid.Row="1">
                    <ListBox Name="listBoxOnLine" Background="AntiqueWhite"/>
                </Grid>
            </Grid>
            <Grid Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock Name="textBlockMessage" Grid.Row="0"
                 Text="对话信息" Background="Beige" TextAlignment="Center"/>
                <ListBox Name="listBoxMessage" Grid.Row="1" BorderThickness="1" Padding="0 5 0 0"/>
                <DockPanel Grid.Row="2">
                    <TextBlock Text="发言:" Margin="10 0 0 0" DockPanel.Dock="Left" VerticalAlignment="Center"/>
                    <Button Name="btnSend" Click="btnSend_Click" Content="发送" Width="50" DockPanel.Dock="Right" Margin="10 0 10 0"/>
                    <TextBox Name="textBoxTalk" KeyDown="textBoxTalk_KeyDown"/>
                </DockPanel>
            </Grid>
        </DockPanel>
    </Grid>
</Window>

c#网编实验五--WCF和TCP消息通信实验文章来源地址https://www.toymoban.com/news/detail-494535.html

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
{
    /// <summary>
    /// ClientWindow.xaml 的交互逻辑
    /// </summary>
    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接口
        /// <summary>有用户登录</summary>
        public void ShowLogin(string loginUserName)
        {
            if (loginUserName == UserName)
            {
                dockPanel1.Visibility = System.Windows.Visibility.Visible;
            }
            listBoxOnLine.Items.Add(loginUserName);
        }

        /// <summary>其他用户退出</summary>
        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
    {
        /// <summary>
        /// 用户退出。参数:登录者用户名
        /// </summary>
        public void Login(string userName)
        {
            OperationContext context = OperationContext.Current;
            IChatServiceCallback callback = context.GetCallbackChannel<IChatServiceCallback>();
            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);
            }
        }

        /// <summary>
        /// 用户退出。参数:退出者用户名
        /// </summary>
        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);
            }
        }

        /// <summary>
        /// 客户端发来的对话信息。参数:发送者用户名,对话内容
        /// </summary>
        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<User> Users { get; set; }

        static CC()
        {
            Users = new List<User>();
        }

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

到了这里,关于c#网编实验五--WCF和TCP消息通信实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA Socket实现实时接收TCP消息,让你的服务端通信更高效!

    本文主要介绍如何利用socket实现实时接收服务端发送的TCP消息。 目录 一、需要掌握 二、程序源码 三、运行演示 网络调试助手下载:https://www.aliyundrive.com/s/6Y8L7Wv5sT6 网络通信协议的理解:JAVA socket是基于TCP/IP协议实现的,需要对TCP/IP协议有一定的了解,包括TCP连接的建立、数

    2024年02月11日
    浏览(42)
  • C#上位机基础学习_基于SOCKET实现与PLC服务器的TCP通信(一)

    测试软件: TIA PORTAL V15.1 S7-PLCSIM ADVANCED V3.0 Visual Studio 2019 如下图所示,打开S7-PLCSIM ADVANCED V3.0仿真软件,新键一个实例,设置仿真PLC的IP地址等参数,然后点击Start激活PLC, 如下图所示,激活PLC后,可以看到已经存在一个实例, 如下图所示,打开TIA PORTAL V15.1,新建一个项目,

    2023年04月15日
    浏览(45)
  • SSE与WebSocket分别实现服务器发送消息通知(Golang、Gin)

    服务端推送,也称为消息推送或通知推送,是一种允许应用服务器主动将信息发送到客户端的能力,为客户端提供了实时的信息更新和通知,增强了用户体验。 服务端推送的背景与需求主要基于以下几个诉求: 实时通知:在很多情况下,用户期望实时接收到应用的通知,如

    2024年02月03日
    浏览(52)
  • OPC通信从入门到精通_1_OPC基础知识及简单C#程序编写(OPCDA,OPCUA简介;OPC通信数据流框架图;C#程序编写)

    OPC的诞生及历史 :软件进行开发时需要与各种不同的协议进行对接,例如Modbus协议等,当设备很多,协议很多的情况下,上位机与硬件的沟通就会变得很麻烦,所以就有了将这些协议抽象出一个标准接口,对于软件人员就无需和协议对接,只需要对接接口即可,因此OPC就诞生

    2024年02月15日
    浏览(50)
  • C#使用TCP进行聊天通信(详细解析)

    TCP通信可以使用Socket和TcpListene进行通信,TcpListene是Socket的一个封装,可以更好的操作Socket,底层依然是socket。 进行通信分为2部分,一个是服务端,一个是客户端。 一,服务端 1.使用TcpListener实例化,得到服务器的ip和端口  myListener = new TcpListener(IPAddress.Parse(textBox1.Text), Co

    2024年02月04日
    浏览(45)
  • 编写C#程序实现和西门子1500PLC进行Modbus Tcp通讯仿真

    前言 本文章的主题是介绍Modbus Tcp通讯仿真,其中C#编写的程序充当客户端(Client),西门子1500PLC充当的服务器端(Server),有关Modbus Tcp协议的具体内容在此也不再赘述,大家可以自行阅读官方文档。 注:在实现其基本功能的条件下,本文的代码编写以及软件配置均简化。

    2024年02月11日
    浏览(68)
  • ModbusRTU\TCP消息帧解析(C#实现报文发送与解析)

    PLC寄存器中存储(整型和无符号整型:2字节。长整型:4字节。单精度浮点数:4字节。双精度浮点数:8字节),我们只要知道数据类型,是2个字节一截取,还是4个字节 ,对接收到的报文进行字节截取然后编码成str就行 向PLC中写入Float,float占4个字节=2个寄存器,所以要使用

    2024年02月03日
    浏览(49)
  • DM9051--TCP通信实验(基于STM32CUBEMX)

    最近作者一直在研究DM9051芯片的工作机理,在此过程中,上网上找了很多资料,但根据资料还是不能了解很通透。因此我直接开始实战,经过多番周折,终于调通了程序。再此篇文章分享下自己的调试过程,也把疑问分享一下!(写的比较潦草,资料在最后) DM9051NP SPI接口网

    2024年02月08日
    浏览(106)
  • C# socket——简单的TCP 客户端 连接通信

    TCP编程的客户端一般步骤是: 1、创建一个socket,用函数socket()。 2、设置socket属性。 3、设置要连接的对方的IP地址和端口等属性。 4、连接服务器,用函数connect()。 5、收发数据,用函数send()和recv(),或者read()和write()。 6、关闭网络连接。 using System; using System.Net; using System.

    2024年02月11日
    浏览(53)
  • 【STM32F1】以太网通信之UDP/TCP实验

    在本实验中,开发板主控芯片通过 SPI 接口与 CH395Q 以太网芯片进行通讯,从而完成对 CH395Q 以太网芯片的功能配置、数据接收等功能,同时将 CH395Q 以太网芯片的 Socket0 配 置为 UDP 模式,并可通过按键发送 UDP 广播数据至其他的 UDP 客户端,也能够接收其他 UDP 客户端广播的数

    2024年02月07日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包