0

我需要一些关于使用套接字的 WPF 聊天应用程序的帮助。问题是它似乎不起作用,所以有人可以指导我我做错了什么。下面你会在后面的代码 WPF 代码中找到我的代码:

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.Windows.Threading;

namespace CSSChat
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        public MainWindow()
        {
            InitializeComponent();
            sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            textLocalIp.Text = GetLocalIP();
            textRemoteIp.Text = GetLocalIP();
        }

        //return own IP
        private string GetLocalIP()
        {
            string ipaddr = null;

            IPHostEntry host;
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipaddr = ip.ToString();
                    return ipaddr;
                }
            }

            //in case we didn't get it
            if (ipaddr == null) throw new ArgumentNullException("IP can not be null in GetLocalIP() ");
            return "127.0.0.1";
        }

        private void MessageCallBack(IAsyncResult ar)
        {
            try
            {
                EndPoint epRemote = new IPEndPoint(IPAddress.Parse(textRemoteIp.Text), Convert.ToInt32(textRemotePort.Text));
                int size = sck.EndReceiveFrom(ar, ref epRemote);

                //check if we got something
                byte[] recvdata = new byte[1464];
                recvdata = (byte[])ar.AsyncState;

                //convert to human-readable
                ASCIIEncoding enc = new ASCIIEncoding();
                string recv_message = enc.GetString(recvdata);

                //adding message to the listbox
                this.Dispatcher.Invoke((Action)(() =>
                {
                    listMessages.Text += "Remote box: " + recv_message;
                    listMessages.Text += "\r\n";
                }));
            //start listening again
            byte[] buf = new byte[1500];
            sck.BeginReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buf);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnStart_Click_1(object sender, RoutedEventArgs e)
        {
            {
                //bind socket
                try
                {
                    this.Dispatcher.Invoke((Action)(() =>
                    {
                        EndPoint eplocal = new IPEndPoint(IPAddress.Parse(textLocalIp.Text), Convert.ToInt32(textLocalPort.Text));
                        sck.Bind(eplocal);

                        //connect to remote IP & Port
                        EndPoint epRemote = new IPEndPoint(IPAddress.Parse(textRemoteIp.Text), Convert.ToInt32(textRemotePort.Text));
                        sck.Connect(epRemote);

                        //start listening
                        byte[] buf = new byte[1500];
                        sck.BeginReceiveFrom(buf, 0, buf.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buf);

                        //send
                        btnStart.Content = "Connected";
                        btnStart.IsEnabled = false;
                        textMessage.Focus();
                    }));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }

        private void btnSend_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                //convert to human-readable 
                ASCIIEncoding enc = new ASCIIEncoding();
                byte[] buf = new byte[1500];
                buf = enc.GetBytes(textMessage.Text);

                //send message
                sck.Send(buf);

                //add to chat window
                    listMessages.Text += "Me: " + textMessage.Text;
                    listMessages.Text += "\r\n";

                    //clear
                    textMessage.Clear();
                }));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

任何反馈将不胜感激,谢谢!

4

1 回答 1

0

解决方案是使用调用程序并将所有事件放入其中

    this.Dispatcher.Invoke(new Action(() =>
{
... your code here ...
}));

或者

//for asynchronous multithreading
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new ThreadsTart(() =>
{
...
})); 

在上面的代码中,两者都这样做。

于 2013-09-30T11:41:12.800 回答