zoukankan      html  css  js  c++  java
  • TCP聊天室



    服务器端

    服务器界面设计xaml

    <Window x:Class="ChatServer.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" 
            Closed="Window_Closed" Loaded="Window_Loaded">
        <Grid>
          <Button Content="启动" Name="btnStart" HorizontalAlignment="Left" Margin="28,29,0,0" VerticalAlignment="Top" Width="105" Height="39" Click="btnStart_Click" />
          <Button Content="停止" Name="btnStop" HorizontalAlignment="Left" Margin="193,29,0,0" VerticalAlignment="Top" Width="108" Height="39" Click="btnStop_Click" />
          <TextBox Name="txtMsg" HorizontalAlignment="Left" Height="200" AcceptsReturn="True"  Margin="28,98,0,0" IsReadOnly="True" TextWrapping="Wrap" 
                   VerticalScrollBarVisibility="Auto" Text="" VerticalAlignment="Top" Width="460"/>
        </Grid>
    </Window>

    后台实现

    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;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.IO;
    
    
    
    namespace ChatServer
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            //保存多个客户端的通信套接字
            public static Dictionary<String, Socket> clientList = null;
            //声明一个监听套接字
            Socket serverSocket = null;
            //设置一个监听标记
            Boolean isListen = true;
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                if (serverSocket == null)
                {
                    try
                    {
                        clientList = new Dictionary<string, Socket>();
                        serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//实例监听套接字
                        IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 8080);//端点
                        serverSocket.Bind(endPoint);//绑定
                        serverSocket.Listen(100);//设置最大连接数
                        Thread th = new Thread(StartListen);
                        th.IsBackground = true;
                        th.Start();
                        txtMsg.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            txtMsg.Text += "服务启动...
    ";
                        }));
                    }
                    catch (SocketException ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
    
                }
            }
    
            //线程函数,封装一个建立连接的通信套接字
            private void StartListen()
            {
                isListen = true;
                Socket clientSocket = default(Socket);
    
                while (isListen)
                {
                    try
                    {
                        clientSocket = serverSocket.Accept();//这个方法返回一个通信套接字
                    }
                    catch (SocketException ex)
                    {
                        File.AppendAllText("E:\Exception.txt", ex.ToString() + "
    StartListen
    " + DateTime.Now.ToString() + "
    ");
                    }
    
                    Byte[] bytesFrom = new Byte[4096];
                    String dataFromClient = null;
                    if (clientSocket != null && clientSocket.Connected)
                    {
                        MessageBox.Show("接收到连接请求");
                           
                        try
                        {
                            Int32 len = clientSocket.Receive(bytesFrom);//获取客户端发来的信息
                            if (len > -1)
                            {
                                String tmp = Encoding.UTF8.GetString(bytesFrom, 0, len);
                                try
                                {
                                    dataFromClient =tmp;
                                }
                                catch (Exception ex)
                                {
    
                                }
    
                                Int32 sublen = dataFromClient.LastIndexOf("$");
                                if (sublen > -1)
                                {
                                    dataFromClient = dataFromClient.Substring(0, sublen);
                                    if (!clientList.ContainsKey(dataFromClient))
                                    {
                                        clientList.Add(dataFromClient, clientSocket);
    
                                        BroadCast.PushMessage(dataFromClient + " Joined ", dataFromClient, false, clientList);
    
                                        HandleClient client = new HandleClient();
    
                                        client.StartClient(clientSocket, dataFromClient, clientList);
    
                                    }
                                    else
                                    {
                                        clientSocket.Send(Encoding.UTF8.GetBytes("#" + dataFromClient + "#"));
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            File.AppendAllText("E:\Exception.txt", ex.ToString() + "
    		" + DateTime.Now.ToString() + "
    ");
                        }
    
                    }
                }
    
    
            }
    
            private void btnStop_Click(object sender, RoutedEventArgs e)
            {
                if (serverSocket != null)
                {
    
                    foreach (var socket in clientList.Values)
                    {
                        socket.Close();
                    }
                    clientList.Clear();
    
                    serverSocket.Close();
                    serverSocket = null;
                    isListen = false;
                    txtMsg.Text += "服务停止
    ";
                }
            }
    
            private void Window_Closed(object sender, EventArgs e)
            {
                isListen = false;
                BroadCast.PushMessage("Server has closed", "", false, clientList);
                clientList.Clear();
                serverSocket.Close();
                serverSocket = null;
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                try
                {
                    clientList = new Dictionary<string, Socket>();
                    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//实例监听套接字
                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 8080);//端点
                    serverSocket.Bind(endPoint);//绑定
                    serverSocket.Listen(100);//设置最大连接数
                    Thread th = new Thread(StartListen);
                    th.IsBackground = true;
                    th.Start();
                    txtMsg.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        txtMsg.Text += "服务启动...
    ";
                    }));
                }
                catch (SocketException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
    
    
        }
    
        //这里专门负责接收客户端发来的消息,并且转发给所有的客户端
        public class HandleClient
        {
            Socket clientSocket;
            String clNo;
            Dictionary<String, Socket> clientList = new Dictionary<string, Socket>();
            public void StartClient(Socket inClientSocket, String clientNo, Dictionary<String, Socket> cList)
            {
                clientSocket = inClientSocket;
                clNo = clientNo;
                clientList = cList;
                Thread th = new Thread(Chat);
                th.IsBackground = true;
                th.Start();
            }
    
            private void Chat()
            {
                Byte[] bytesFromClient = new Byte[4096];
                String dataFromClient;
                String msgTemp = null;
                Byte[] bytesSend = new Byte[4096];
                Boolean isListen = true;
    
                while (isListen)
                {
                    try
                    {
                        Int32 len = clientSocket.Receive(bytesFromClient);
                        if (len > -1)
                        {
                            dataFromClient = Encoding.UTF8.GetString(bytesFromClient, 0, len);
                            if (!String.IsNullOrWhiteSpace(dataFromClient))
                            {
                                dataFromClient = dataFromClient.Substring(0, dataFromClient.LastIndexOf("$"));
                                if (!String.IsNullOrWhiteSpace(dataFromClient))
                                {
                                    BroadCast.PushMessage(dataFromClient, clNo, true, clientList);
                                    msgTemp = clNo + ": " + dataFromClient + "		" + DateTime.Now.ToString();
                                    String newMsg = msgTemp;
                                    File.AppendAllText("E:\MessageRecords.txt", newMsg + "
    ", Encoding.UTF8);
                                }
                                else
                                {
                                    isListen = false;
                                    clientList.Remove(clNo);
                                    clientSocket.Close();
                                    clientSocket = null;
                                }
    
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        isListen = false;
                        clientList.Remove(clNo);
                        clientSocket.Close();
                        clientSocket = null;
                        File.AppendAllText("E:\Exception.txt", ex.ToString() + "
    Chat
    " + DateTime.Now.ToString() + "
    ");
                    }
                }
            }
        }
    
        //向所有的客户端发送消息
        public class BroadCast
        {
            public static void PushMessage(String msg, String uName, Boolean flag, Dictionary<String, Socket> clientList)
            {
                foreach (var item in clientList)
                {
                    Socket brdcastSocket = (Socket)item.Value;
                    String msgTemp = null;
                    Byte[] castBytes = new Byte[4096];
                    if (flag == true)
                    {
                        msgTemp = uName + ": " + msg + "		" + DateTime.Now.ToString();
                        castBytes = Encoding.UTF8.GetBytes(msgTemp);
                    }
                    else
                    {
                        msgTemp = msg + "		" + DateTime.Now.ToString();
                        castBytes = Encoding.UTF8.GetBytes(msgTemp);
                    }
                    try
                    {
                        brdcastSocket.Send(castBytes);
                    }
                    catch (Exception ex)
                    {
                        brdcastSocket.Close();
                        brdcastSocket = null;
                        File.AppendAllText("E:\Exception.txt", ex.ToString() + "
    PushMessage
    " + DateTime.Now.ToString() + "
    ");
                        continue;
                    }
    
                }
            }
        }
    }
    




    客户端

    客户端界面设计xaml

    <Window x:Class="ChatRoom.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525"
           Closed="Window_Closed_1" Activated="Window_Activated_1" 
            WindowStartupLocation="CenterScreen" >
        <Window.Resources>
            <RoutedUICommand x:Key="SendMessageShortcutKey" Text="Send Message Shortcut Key"></RoutedUICommand>
        </Window.Resources>
        <Window.InputBindings>
            <KeyBinding Gesture="Ctrl+Enter" Command="{StaticResource SendMessageShortcutKey}"></KeyBinding>
        </Window.InputBindings>
        <Window.CommandBindings>
            <CommandBinding Command="{StaticResource SendMessageShortcutKey}" CanExecute="CommandBinding_SendMessage_CanExecute" Executed="CommandBinding_SendMessage_Executed">
            </CommandBinding>
        </Window.CommandBindings>
    
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="50"></RowDefinition>
                <RowDefinition Height="250"></RowDefinition>
                <RowDefinition Height="150"></RowDefinition>
                <RowDefinition Height="80"></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Orientation="Horizontal">
                <Label  Name="lbMsg" Content="设置你的用户名:" Margin="10,10"></Label>
                <TextBox Name="txtName" Width="200" Height="30" FontSize="16"></TextBox>
                <Button Name="btnConnect" Content="连接服务器" Width="100" Height="30" Margin="15,8" Click="btnConnect_Click"></Button>
            </StackPanel>
            <TextBox Grid.Row="1" Name="txtReceiveMsg" Margin="10,10.4,10.4,159.2" BorderBrush="DarkGreen" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Foreground="DarkBlue" IsReadOnly="True"></TextBox>
            <TextBox Grid.Row="1" Name="txtSendMsg" Margin="10,99.4,9.4,0" AcceptsReturn="True" BorderBrush="DarkBlue" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Height="99" VerticalAlignment="Top"/>
            <Button Grid.Row="1" Name="btnSend" Content="发送(Ctrl+Enter)" Width="100" Height="30" Click="btnSend_Click" RenderTransformOrigin="0.478,0.613" Margin="210,209.4,208.4,10.2"></Button>
        </Grid>
    </Window>
    


    后台代码

    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;
    using System.Runtime.InteropServices;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    
    namespace ChatRoom
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
    //窗口闪烁代码
            public const UInt32 FLASHW_STOP = 0;
            public const UInt32 FLASHW_CAPTION = 1;
            public const UInt32 FLASHW_TRAY = 2;
            public const UInt32 FLASHW_ALL = 3;
            public const UInt32 FLASHW_TIMER = 4;
            public const UInt32 FLASHW_TIMERNOFG = 12;
            [DllImport("user32.dll")]
            static extern bool FlashWindowEx(ref FLASHWINFO pwfi);
    
            [DllImport("user32.dll")]
            static extern bool FlashWindow(IntPtr handle, bool invert);
    
            [DllImport("user32.dll")]
            public static extern IntPtr GetForegroundWindow();
    
            Socket clientSocket = null;
            static Boolean isListen = true;
            private void btnSend_Click(object sender, RoutedEventArgs e)
            {
                SendMessage();
            }
    
            private void SendMessage()
            {
                if (String.IsNullOrWhiteSpace(txtSendMsg.Text.Trim()))
                {
                    MessageBox.Show("发送内容不能为空哦~");
                    return;
                }
                if (clientSocket != null && clientSocket.Connected)
                {
                    String sendMsg = txtSendMsg.Text + "$";
                    Byte[] bytesSend = Encoding.UTF8.GetBytes(sendMsg);
                    clientSocket.Send(bytesSend);
                    txtSendMsg.Text = "";
                }
                else
                {
                    MessageBox.Show("未连接服务器或者服务器已停止,请联系管理员~");
                    return;
                }
            }
    
    
            /// <summary>
            /// 每一个连接的客户端必须设置一个唯一的用户名,在服务端是把用户名和通信套接字
            /// 保存在Dictionary<UserName,ClientSocket>.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnConnect_Click(object sender, RoutedEventArgs e)
            {
                if (String.IsNullOrWhiteSpace(txtName.Text.Trim()))
                {
                    MessageBox.Show("还是设置一个用户名吧,这样别人才能认识你哦~");
                    return;
                }
    
                if (clientSocket == null || !clientSocket.Connected)
                {
                    try
                    {
                        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        clientSocket.BeginConnect(IPAddress.Loopback, 8080, (args) =>
                        {
                            if (args.IsCompleted)
                            {
                                Byte[] bytesSend = new Byte[4096];
                                txtName.Dispatcher.BeginInvoke(new Action(() =>
                                {
                                    String tmp = txtName.Text.Trim() + "$";
                                    bytesSend = Encoding.UTF8.GetBytes(tmp);
                                    if (clientSocket != null && clientSocket.Connected)
                                    {
                                        clientSocket.Send(bytesSend);
                                        txtName.IsEnabled = false;
                                        txtSendMsg.Focus();
                                        Thread th = new Thread(DataFromServer);
                                        th.IsBackground = true;
                                        th.Start();
    
                                    }
                                    else
                                    {
                                        MessageBox.Show("服务器已经关闭");
                                    }
                                }));
    
    
                            }
                        }, null);
    
                    }
                    catch (SocketException ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
    
                }
                else
                {
                    MessageBox.Show("You has already connected with Server");
                }
            }
    
            private void ShowMsg(String msg)
            {
                txtReceiveMsg.Dispatcher.BeginInvoke(new Action(() =>
                {
                    txtReceiveMsg.Text += Environment.NewLine + msg;
                    txtReceiveMsg.ScrollToEnd();
                    IntPtr handle = new System.Windows.Interop.WindowInteropHelper(this).Handle;
                    if (this.WindowState == WindowState.Minimized || handle != GetForegroundWindow())
                    {
                        FLASHWINFO fInfo = new FLASHWINFO();
    
                        fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
                        fInfo.hwnd = handle;
                        fInfo.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
                        fInfo.uCount = UInt32.MaxValue;
                        fInfo.dwTimeout = 0;
    
                        FlashWindowEx(ref fInfo);
                    }
                }));
    
            }
    
            //获取服务端的消息
            private void DataFromServer()
            {
                ShowMsg("Connected to the Chat Server...");
                isListen = true;
                try
                {
    
                    while (isListen)
                    {
                        Byte[] bytesFrom = new Byte[4096];
                        Int32 len = clientSocket.Receive(bytesFrom);
    
    
                        String dataFromClientTmp = Encoding.UTF8.GetString(bytesFrom, 0, len);
                        if (!String.IsNullOrWhiteSpace(dataFromClientTmp))
                        {
                            String dataFromClient = dataFromClientTmp;
                            if (dataFromClient.StartsWith("#") && dataFromClient.EndsWith("#"))
                            {
                                String userName = dataFromClient.Substring(1, dataFromClient.Length - 2);
                                this.Dispatcher.BeginInvoke(new Action(() =>
                                {
    
                                    MessageBox.Show("用户名:[" + userName + "]已经存在,请尝试其它用户名");
                                }));
                                isListen = false;
                                txtName.Dispatcher.BeginInvoke(new Action(() =>
                                {
                                    txtName.IsEnabled = true;
                                    clientSocket = null;
                                }));
    
                            }
                            else
                            {
                                ShowMsg(dataFromClient);
                            }
                        }
                    }
                }
                catch (SocketException ex)
                {
                    isListen = false;
                    if (clientSocket != null && clientSocket.Connected)
                    {
                        //我没有在客户端关闭连接而是向服务端发送一个消息,在服务器端关闭,这样主要
                        //为了异常的处理放到服务端。客户端关闭会抛异常,服务端也会抛异常。
                        clientSocket.Send(Encoding.UTF8.GetBytes("$"));
                        MessageBox.Show(ex.ToString());
                    }
    
                }
            }
    
            //这是定义了一个发送的快捷键,WPF的知识
            private void CommandBinding_SendMessage_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (String.IsNullOrWhiteSpace(txtSendMsg.Text.Trim()))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
    
            }
    
            private void CommandBinding_SendMessage_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                SendMessage();
            }
    
            private void Window_Activated_1(object sender, EventArgs e)
            {
    
                txtSendMsg.Focus();
    
            }
    
            private void Window_Closed_1(object sender, EventArgs e)
            {
                if (clientSocket != null && clientSocket.Connected)
                {
                    clientSocket.Send(Encoding.UTF8.GetBytes("$"));
                }
            }
        }
        public struct FLASHWINFO
        {
    
            public UInt32 cbSize;
            public IntPtr hwnd;
            public UInt32 dwFlags;
            public UInt32 uCount;
            public UInt32 dwTimeout;
        }
    }
    


    版权声明:

  • 相关阅读:
    WebApi Ajax 跨域请求解决方法(CORS实现)
    JQuery Ajax POST/GET 请求至 ASP.NET WebAPI
    Hybird APP对接后台:Net WebApi
    Chrome
    centos8平台:用fontconfig安装及管理字体(fc-list/fc-match/fc-cache)
    centos8平台:redis6配置启用io多线程(redis6.0.1)
    centos8平台安装redis6.0.1
    centos8平台:举例讲解redis6的ACL功能(redis6.0.1)
    ImageMagick实现图片加水印(ImageMagick6.9.10)
    centos8上安装ImageMagick6.9.10并压缩图片生成webp缩略图
  • 原文地址:https://www.cnblogs.com/walccott/p/4957057.html
Copyright © 2011-2022 走看看