在论坛里看见diaodiaop高人回复的关于socket一个服务器端连多个客户端的控制台代码,经测试很好。现在要改成窗体程序,本人初学,始终不能把接收到的数据传给listbox控件,已经搞了3天,还是不行。现请教各位高人,应该怎样做,谢谢!代码如下:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;namespace socket一对多通信
{
    class Program
    {
        static byte[] buffer = new byte[1024];
        static void Main(string[] args)
        {
            try
            {
                Dictionary<string, int> server = new Dictionary<string, int>();
                server.Add("192.168.53.53", 4999);
                server.Add("192.168.53.54", 4998);
                server.ToList().AsParallel().ForAll(item =>
                    {
                        Console.WriteLine("con");
                        var client = new TcpClient();
                        client.Connect(item.Key, item.Value);
                        client.Client.BeginReceive(buffer, 0, buffer.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
                    });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();   
        }        static void ReceiveMessage(IAsyncResult ar)
        {
            var socket = ar.AsyncState as TcpClient;
            try
            {
                var length = socket.Client.EndReceive(ar);
                byte[] reallData = new byte[length];
                Array.Copy(buffer, reallData, length);
                ThreadPool.QueueUserWorkItem(new WaitCallback((state) => { doWork(new objectState() { s = socket, data = reallData }); }));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                socket.Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
        }
        static void doWork(object o)
        {
            DateTime dt = DateTime.Now;            var rs = o as objectState;
            var a = string.Join("-", rs.data.Select(d => d.ToString("X2")).ToArray());
            Console.WriteLine(dt + " " + rs.s.Client.RemoteEndPoint.ToString() + "  当前线程ID: " + Thread.CurrentThread.ManagedThreadId);//获取连接的服务器端的IP和PORT 获取当前线程的标识符ID
            Console.WriteLine(a);
            //Console.WriteLine(Thread.CurrentThread.ThreadState);//获取当前线程的类型,后台线程,还是其他
        }
    }    public class objectState
    {
        public TcpClient s { get; set; }
        public byte[] data { get; set; }
    }
}

解决方案 »

  1.   

    所有 Console.WriteLine 的都是输出内容你并没有贴出你的 窗体程序代码,泛泛的说没意义
      

  2.   

            前台控件从来都不是用来获取数据得存储主体,而是浏览显示数据用的,如果你以这种思路考虑问题,就没这么多疑惑页面最常用得方法是,后台更新数据源,通知前台变更(通过线程Message,或者线程event,甚至简单到就是个变量更新标志位),主要目的是告知前台,要刷新页面控件页面通过捕捉通知,主动根据数据源更新页面C#也提供了完整得数据源绑定方法,他的流程就是这样得,每个绑定都提供UpdateTarget和UpdateSource方法,来用来更新数据源或者更新控件,数据源和控件式关联关系,只是很多新手并不知道C#还有这个东西,也不会用,或者不习惯用,但人家得思路式正确得UI界面得更新思路,从MFC开始微软都是走这个思路制作框架
          
      

  3.   

    软件设计都是分层的,这个分层的概念,就叫做设计。设计是循序渐进的,设计也需要经过培训,不是抄最初刚学编程时的几条代码就能学会软件设计的。比如说窗体里边可能定义    public partial class Form1 : Form
        {
            private MyServer Server = new MyServer("211.122.134.78:3388");        public Form1()
            {
                InitializeComponent();
                Server.ReceiveMessage += ......
            }
    这类的代码,每一个窗体都分别连到服务器,并且监听服务器传来的完整消息事件。也可能是使用一个 static 的变量来保存全局的进程使用一个连接到服务器的处理对象。事件处理方法中,如何访问窗体,是你自己需要编程设计的。比如说上述代码中就可以直接以匿名委托方式访问 this.BeginInvoke 方式访问当前窗体。因为通讯处理过程通常都是在设计编写各种窗体之前设计开发的,所以通讯模块并不依赖于窗体,窗体对象应该监听通讯对象抛出的事件、然后把消息显示在窗体内部。你了解这个设计模式,才刚刚对设计有所理解。不懂设计的人,总也不能理解依赖倒置的基本思想!
      

  4.   

    你可能唯一能想到的就是接受了消息之后如何去找到要显示的窗体。如果“开窍”,搞懂软件设计入门,你就要学会依赖倒置的各种编程设计模式,也就是事件驱动设计模式。通讯模块从来不依赖窗体,相反地,是窗体去(类似 Server 对象这类)通讯对象上去注册监听“消息到来”的事件,并且窗体显示消息到自己的控件上。并不是什么通讯模块传数据到 UI 的控件。要把基本方向搞对,抄来的代码才更有意义。否则一开始抄的代码就与设计思想反了,将来会越来越糟糕。
      

  5.   

    都跟你说了,你打算或已经把 class Program 里的代码写到哪里了,这个很重要!
    如果写在单独的类中,就需要通过事件与 Form 沟通
    如果写在 Form 类中,那就已经可以直接赋值了(Form 都有相应的方法)
    如果你连架构都没有确定,那么给你代码又有什么意义呢
      

  6.   

    没法改
    你贴的代码里,大致看了下
    Dictionary<string, int> server = new Dictionary<string, int>();
                    server.Add("192.168.53.53", 4999);
                    server.Add("192.168.53.54", 4998);
    这段,是用来模拟服务器端“监听”到的数据的你得从根本上学习socket编程,不是什么UI控件的问题每台客户端需要和服务端建立连接,服务器不断监听客户端发来的信息,并做处理,显示等