哪位达人能提供多线程,Socket的C#实例代码,谢谢?
编译环境:VS2005

解决方案 »

  1.   

    首先必须包含的两个命名空间:Using System.Net;Using System.Net.Sockets;几个常用的类:(这些东西,查下MSDN就很详细了)IPHostEntry, Dns,IPAddress,IPEndPoint,还有最重要的SocketIPEndPoint: 这个是网络终结点,很好理解,就是网络上一个固定的地址:一个IP与一个端口的组合.下面我还是以我以前写的一个很简单的聊天程序做示例吧, (很短代码的)Form1.cs//说明下, 这个是集Server与Client与一体的.using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;   //这个和上面的是使用Socket必须的.
    using System.IO;      
    using System.Threading;      //这个是使用多线程必需的.namespace OnlySocket
    {
        public partial class Form1 : Form           //partial表示这块代码只是Form1类的部分, Form1类继承自Form类
        {
            public Form1()
            {
                InitializeComponent();    //构造函数, 初始化容器.
            }
            Socket sock;          //定义一个Socket类的对象 (默认为protected)
            Thread th;             //定义一个Thread类的对象
            //        public static IPAddress GetServerIP()        //静态函数, 无需实例化即可调用.
            {
                IPHostEntry ieh = Dns.GetHostByName(Dns.GetHostName()); //不多说了, Dns类的两个静态函数             //或用DNS.Resolve()代替GetHostName()
                return ieh.AddressList[0];                  //返回Address类的一个实例. 这里AddressList是数组并不奇怪,一个Server有N个IP都有可能
            }
                  private void BeginListen()               //Socket监听函数, 等下作为创建新线程的参数
            {
                IPAddress serverIp = GetServerIP();         //调用本类静态函数GetServerIP得到本机IPAddress.
                IPEndPoint iep = new IPEndPoint(serverIp, Convert.ToInt32(tbPort.Text));    //本地终结点
                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //实例化内成员sock
                Byte[] byteMessage = new Byte[100]; //存放消息的字节数组缓冲区, 注意数组表示方法,和C不同的.
                this.lbIep.Text = iep.ToString();         
                sock.Bind(iep);                                  //Socket类的一个重要函数, 绑定一个IP,
                while (true)                     //这里弄了个死循环来监听端口, 有人会问死循环了,那程序不卡住了, 注意这只是个类, 这里还没有main函数呢.
                {
                    try
                    {
                        sock.Listen(5);             //好了,sock绑定了本地终结点就可以开始监听了,5表示最大连接数为5
                        Socket newSock = sock.Accept();     //这里又有Socket类的一个重要的方法:Accept, 该方法接受来自外面的Socket连接请求, 并返回一个Socket套接字, 这个套接字就开始处理这一个client与Server之间的对话
                        newSock.Receive(byteMessage); //接受client发送过来的数据保存到缓冲区.
                        string msg = "From [" + newSock.RemoteEndPoint.ToString() + "]:" +System.Text.Encoding.UTF8.GetString(byteMessage)+"\n";   //GetString()函数将byte数组转换为string类型.
                        rtbTalk.AppendText(msg+"\n");        //显示在文本控件里
                    }
                    catch (SocketException se)              //捕捉异常,
                    {
                        lbState.Text = se.ToString();       //将其显示出来, 在此亦可以自定义错误.
                    }
                }
            }        private void btConnect_Click(object sender, EventArgs e)   //连接按钮触发的事件: 连接Server
            {
                btConnect.Enabled = false;
                btStopConnect.Enabled = true;
                try
                {
                    th = new Thread(new ThreadStart(BeginListen));          //创建一个新的线程专门用于处理监听,这句话可以分开写的,比如: ThreadStart ts=new ThreadStart(BeginListen); th=new Thread (ts); 不过要注意, ThreadStart的构造函数的参数一定要是无参数的函数. 在此函数名其实就是其指针, 这里是委托吗?
                    th.Start();                            //启动线程
                    lbState.Text = "Listenning...";
                }
                catch (SocketException se)           //处理异常
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (ArgumentNullException ae)   //参数为空异常
                {
                    lbState.Text = "参数错误";
                    MessageBox.Show(ae.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }        }        private void btStopConnect_Click(object sender, EventArgs e)  //停止监听
            {
                btStopConnect.Enabled = false;
                btConnect.Enabled = true;
                sock.Close();                     //关闭套接字
                th.Abort();                         //终止监听线程
               
               lbState.Text = "Listenning stopped";
            }        private void btExit_Click(object sender, EventArgs e)       
            {
                sock.Close();
                th.Abort();
                Dispose();             //清理资源,就是释放内存
                this.Close();          //关闭对话框, 退出程序
            }        private void btSend_Click(object sender, EventArgs e)
            {
                try
                {
                    IPAddress clientIp = IPAddress.Parse(tbTargetIp.Text);    //类IPAddress的静态函数Parse() :将Text转化为IPAddress的一个实例.
                    int clientPort = Convert.ToInt32(tbPort.Text);                 //C#的这些转化函数很方便的,不像C++那样麻烦
                    IPEndPoint clientIep = new IPEndPoint(clientIp, clientPort);     //这里用client表示不是很好...., 
                    Byte[] byte_Message;
                    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            实例化的时候还有很多参数的, 这个是Tcp的. Tcp的SocketType是Stream:数据流, 如果协议类型是UDP, 则是数据包传送, QQ就是用的UDP.
                    socket.Connect(clientIep); //Socket的又一个函数Connect(IPEndPoint) .连接远程套接字
                    byte_Message = System.Text.Encoding.UTF8.GetBytes(rtbWords.Text); //发现UTF8可支持中文,就用之
                    socket.Send(byte_Message);
                    rtbTalk.AppendText("\n"+"My words:" + rtbWords.Text + "\n");
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                }
                catch (ArgumentNullException ae)
                {
                    MessageBox.Show(ae.Message,"参数为空",MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.Message, "出现问题", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
           
        }
    }Program.csusing System;
    using System.Collections.Generic;
    using System.Windows.Forms;namespace OnlySocket
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()        //这儿才是main函数        {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
    写了半天了, 够累的了, 虽然都是很基础的东西, 我自己写的时候也复习了一边 , 呵呵.其实多线程我自己也不是很熟练, 记得去年暑假写过一个多线程扫描器, 也不知为啥, 线程开到50以上就异常, 很郁闷的. 其实当时我就是用的new Thread=Thread(new ThreadStart(Fun))实现的, 方法感觉很笨拙,呵呵.大致代码好像是这样的吧:先写个Scan类:public class Scan{try{ public Scan(){   ...Init...   }            public void Scan{ ..task循环扫描... } //task结构体里面有IP, 端口, 是否已扫描标记fLag}catch{}}然后主函数里面可以这样搞:Scan[] scanner = new Scan[XX]Thread[] thread = new Thread[XX];
                for (int i = 0; i < XX;i++)
                {
                    scanner[i] = new Scan(this, i);
                    thread[i] = new Thread(new ThreadStart(scanner[i].StartScan));
                    thread[i].Start();            }其实这样就可以简单的实现多线程了.
    http://hi.baidu.com/small_%BE%C5/blog/item/7f251f547e8af6c2b745aecb.html
      

  2.   

    你可以到fourm.meslog.cn 有一个点菜系统服务器开源的,里面应该有你要的.
      

  3.   

    参考:
    http://www.cnblogs.com/Silverlight_Team/archive/2009/03/13/1411136.html
    http://hi.baidu.com/small_%BE%C5/blog/item/7f251f547e8af6c2b745aecb.html
    http://blog.csdn.net/yagebu1983/archive/2008/03/04/2147210.aspx
      

  4.   

    http://download.csdn.net/source/259316
    http://www.google.cn/search?hl=zh-CN&newwindow=1&q=c%23+socket+%E4%BE%8B%E5%AD%90
      

  5.   

    http://download.csdn.net/source/1095100
    下载一个我 以前写的简单列子。很容易看明白的。
      

  6.   

    正好做这个
    //client端
    using System;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Net.Sockets; 
    namespace socketsample
    {
     class Class1
     {
      static void Main()
      {
       try
       {
        int port = 2000;
        string host = "127.0.0.1";
        IPAddress ip = IPAddress.Parse(host);
        IPEndPoint ipe = new IPEndPoint(ip, port);
        Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        c.Connect(ipe);
        string sendStr = "hello!This is a socket test";
        byte[] bs = Encoding.ASCII.GetBytes(sendStr);
        c.Send(bs, bs.Length, 0);
        string recvStr = "";
        byte[] recvBytes = new byte[1024];
        int bytes;
        bytes = c.Receive(recvBytes, recvBytes.Length, 0);
        recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
        Console.WriteLine(recvStr);
        c.Close();
       }
       catch (ArgumentNullException e)
       {
        Console.WriteLine("ArgumentNullException: {0}", e);
       }
       catch (SocketException e)
       {
        Console.WriteLine("SocketException: {0}", e);
       }
       Console.ReadLine();
      }
     }
    }//server端
    using System;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    namespace Project1
    {
     class Class2
     {
      static void Main()
      {
       try
       {
        int port = 2000;
        string host = "127.0.0.1";
        IPAddress ip = IPAddress.Parse(host);
        IPEndPoint ipe = new IPEndPoint(ip, port);
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        s.Bind(ipe);
        s.Listen(0);
        Socket temp = s.Accept();
        string recvStr = "";
        byte[] recvBytes = new byte[1024];
        int bytes;
        bytes = temp.Receive(recvBytes, recvBytes.Length, 0);
        recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
        Console.WriteLine(recvStr);
        string sendStr = "Ok!Sucess!";
        byte[] bs = Encoding.ASCII.GetBytes(sendStr);
        temp.Send(bs, bs.Length, 0);
        temp.Shutdown(SocketShutdown.Both);
        temp.Close();
        s.Shutdown(SocketShutdown.Both);
        s.Close();
       }
       catch (ArgumentNullException e)
       {
        Console.WriteLine("ArgumentNullException: {0}", e);
       }
       catch (SocketException e)
       {
        Console.WriteLine("SocketException: {0}", e);
       }
       Console.ReadLine();
      }
     }
    }
      

  7.   

    参考这两个C#程序(含注释) 
    http://showjim.qsh.eu/source/cs/sys/net/tcpListener.cs.txt 
    http://showjim.qsh.eu/source/cs/sys/net/tcpClient.cs.txt 
    参考缓存应用 
    http://showjim.qsh.eu/source/cs/sys/net/remoteCache/cacheServer.cs.txt 
    http://showjim.qsh.eu/source/cs/sys/net/remoteCache/cacheClient.cs.txt 
    参考其它应用 
    http://showjim.qsh.eu/source/cs/sql/databaseMessage/messageServer.cs.txt 
    http://showjim.qsh.eu/source/cs/sql/databaseMessage/messageClient.cs.txt 
      

  8.   

    我写过两个TCP和UDP异步socket的例子,里面用到的多线程,道理是一样,如果不使用异步,就是来一个连接开启一个线程,只是异步由操作系统管理了多线程
      

  9.   

    使用System.Net.Sockets 编写的P2P 聊天软件 
    http://szitr.com/bbs/thread-321-1-1.html
      

  10.   

    C# SOCKET 实例大全