You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为双向通信聊天系统添加文本对齐与时间戳功能

实现聊天消息左右对齐与时间戳功能的解决方案

我帮你调整了代码,实现了接收消息左对齐、发送消息右对齐以及添加时间戳的功能,核心是用RichTextBox替代原来的TextBox(因为TextBox无法实现局部文本对齐),同时在收发消息时嵌入时间戳,并且处理了跨线程UI更新的问题:

修改后的服务器代码

namespace Full_Chatt_Server {
    public partial class Form1 : Form {
        TcpListener listener;
        TcpClient klient;
        int port;
        public Form1() {
            InitializeComponent();
            // 确保tbxMessage是RichTextBox控件
            tbxMessage.SelectionAlignment = HorizontalAlignment.Left;
        }

        private string GetTimestamp()
        {
            return $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]";
        }

        private void btnStartServer_Click(object sender, EventArgs e) {
            btnTaEmot.Enabled = false;
            if (!int.TryParse(tbxPort.Text, out port))
            {
                MessageBox.Show("请输入有效的端口号", Text);
                return;
            }
            try {
                listener = new TcpListener(IPAddress.Any, port);
                listener.Start();
            } catch (Exception error) {
                MessageBox.Show(error.Message, Text);
                return;
            }
            StartAccepting();
        }

        public async void StartAccepting() {
            try {
                klient = await listener.AcceptTcpClientAsync();
            } catch (Exception error) {
                MessageBox.Show(error.Message, Text);
                return;
            }
            StartReading(klient);
        }

        public async void StartReading(TcpClient k) {
            byte[] buffer = new byte[1024];
            int n = 0;
            try {
                n = await k.GetStream().ReadAsync(buffer, 0, 1024);
            } catch (Exception error) {
                MessageBox.Show(error.Message, Text);
                return;
            }
            if (n > 0)
            {
                string receivedMsg = Encoding.Unicode.GetString(buffer, 0, n);
                UpdateChatMessage($"{GetTimestamp()} 对方: {receivedMsg}", HorizontalAlignment.Left);
            }
            StartReading(k);
        }

        private void btnSend_Click(object sender, EventArgs e) {
            string chatt = tbxChatt.Text.Trim();
            if (string.IsNullOrEmpty(chatt)) return;
            
            StartSending(chatt);
            tbxChatt.Clear();
            UpdateChatMessage($"{GetTimestamp()} 我: {chatt}", HorizontalAlignment.Right);
        }

        public async void StartSending(string message) {
            if (klient?.Connected ?? false) {
                byte[] OutStream = Encoding.Unicode.GetBytes(message);
                try {
                    await klient.GetStream().WriteAsync(OutStream, 0, OutStream.Length);
                } catch (Exception error) {
                    MessageBox.Show(error.Message, Text);
                    return;
                }
            }
        }

        // 安全更新聊天消息(处理跨线程UI访问)
        private void UpdateChatMessage(string message, HorizontalAlignment alignment)
        {
            if (tbxMessage.InvokeRequired)
            {
                tbxMessage.Invoke(new Action<string, HorizontalAlignment>(UpdateChatMessage), message, alignment);
                return;
            }
            tbxMessage.SelectionStart = tbxMessage.TextLength;
            tbxMessage.SelectionLength = 0;
            tbxMessage.SelectionAlignment = alignment;
            tbxMessage.AppendText($"{message}\r\n");
            tbxMessage.ScrollToCaret(); // 自动滚动到最新消息
        }
    }
}

修改后的客户端代码

namespace Full_Chatt_Klient {
    public partial class Form1 : Form {
        TcpClient klient = new TcpClient();
        int port;
        public Form1() {
            InitializeComponent();
            // 确保tbxMessage是RichTextBox控件
            tbxMessage.SelectionAlignment = HorizontalAlignment.Left;
        }

        private string GetTimestamp()
        {
            return $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}]";
        }

        private void btnConnect_Click(object sender, EventArgs e) {
            if (!klient.Connected) {
                Connect();
            }
        }

        public async void Connect() {
            if (!IPAddress.TryParse(tbxIP.Text, out IPAddress address))
            {
                MessageBox.Show("请输入有效的IP地址", Text);
                return;
            }
            if (!int.TryParse(tbxPort.Text, out port))
            {
                MessageBox.Show("请输入有效的端口号", Text);
                return;
            }
            try {
                await klient.ConnectAsync(address, port);
                StartReading(klient);
            } catch (Exception error) {
                MessageBox.Show(error.Message, Text);
                return;
            }
            btnSkicka.Enabled = true;
            btnAnslut.Enabled = false;
        }

        private void btnSend_Click(object sender, EventArgs e) {
            string chatt = tbxChatt.Text.Trim();
            if (string.IsNullOrEmpty(chatt)) return;
            
            StartSending(chatt);
            tbxChatt.Clear();
            UpdateChatMessage($"{GetTimestamp()} 我: {chatt}", HorizontalAlignment.Right);
        }

        public async void StartSending(string message) {
            if (klient?.Connected ?? false) {
                byte[] OutStream = Encoding.Unicode.GetBytes(message);
                try {
                    await klient.GetStream().WriteAsync(OutStream, 0, OutStream.Length);
                } catch (Exception error) {
                    MessageBox.Show(error.Message, Text);
                    return;
                }
            }
        }

        public async void StartReading(TcpClient k) {
            byte[] buffer = new byte[1024];
            int n = 0;
            try {
                n = await k.GetStream().ReadAsync(buffer, 0, 1024);
            } catch (Exception error) {
                MessageBox.Show(error.Message, Text);
                return;
            }
            if (n > 0)
            {
                string receivedMsg = Encoding.Unicode.GetString(buffer, 0, n);
                UpdateChatMessage($"{GetTimestamp()} 对方: {receivedMsg}", HorizontalAlignment.Left);
            }
            StartReading(k);
        }

        // 安全更新聊天消息(处理跨线程UI访问)
        private void UpdateChatMessage(string message, HorizontalAlignment alignment)
        {
            if (tbxMessage.InvokeRequired)
            {
                tbxMessage.Invoke(new Action<string, HorizontalAlignment>(UpdateChatMessage), message, alignment);
                return;
            }
            tbxMessage.SelectionStart = tbxMessage.TextLength;
            tbxMessage.SelectionLength = 0;
            tbxMessage.SelectionAlignment = alignment;
            tbxMessage.AppendText($"{message}\r\n");
            tbxMessage.ScrollToCaret(); // 自动滚动到最新消息
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
            if (klient != null) {
                klient.Close();
            }
        }
    }
}

关键修改说明

  • 替换控件类型:把原来的TextBox(tbxMessage)换成RichTextBox,因为只有RichTextBox支持对局部文本设置对齐方式。
  • 时间戳生成:新增GetTimestamp()方法,生成格式为[yyyy-MM-dd HH:mm:ss]的时间字符串,方便查看消息发送/接收时间。
  • 跨线程UI更新:添加UpdateChatMessage()方法,用Invoke处理异步线程中更新UI的问题,避免WinForms跨线程访问异常。
  • 消息对齐控制:发送消息时设置HorizontalAlignment.Right(右对齐),接收消息时设置HorizontalAlignment.Left(左对齐),模拟真实聊天软件布局。
  • 输入校验:新增端口号、IP地址的合法性校验,避免无效输入导致的异常。
  • 自动滚动:添加ScrollToCaret()方法,确保最新消息始终可见。

内容的提问来源于stack exchange,提问作者EricC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:53:16