YangLei's

导航

 

基本思路是:

  1》服务端监听(用一个公用的端口接收连接的请求如:6666)。 2》客户机请求连接端口为6666 3》服务器接受请求然后再监听一个新的端口,再把这个端口发送给客户机。

  4》客户机接到发来的端口,再重新连接服务器此端口。5》服务器保存每一个连接的客户机。

服务端s代码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using System.Threading;

namespace 多端口服务端
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            slist = aa =>
            {
                listBox1.Items.Add(aa);
            };
        }
        private int localPort = 6666;
        private delegate void SetListBoxCallBack(string str);
        private SetListBoxCallBack slist;
        private static int PID = 6667;
        private static ArrayList clientList = new ArrayList();
        private void button1_Click(object sender, EventArgs e)
        {
            AcceptConnection();
        }
        //开始监听的回调函数
        private void AcceptConnection()
        {
            try
            {
                Socket mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint localEP = new IPEndPoint(IPAddress.Any, localPort);
                // 将 Socket 绑定到本地的终结点上
                mainSocket.Bind(localEP);
                // 开始侦听,最大的连接数是 50
                mainSocket.Listen(50);
                mainSocket.BeginAccept(new AsyncCallback(AcceptCallBack), mainSocket);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        //接收连接的回调函数
        private void AcceptCallBack(IAsyncResult iar)
        {
            try
            {
                Socket mainSocket = (Socket)iar.AsyncState;
                // 调用EndAccept完成BeginAccept异步调用,返回一个新的Socket处理与客户的通信
                Socket workerSocket = mainSocket.EndAccept(iar);
               
                if (mainSocket.LocalEndPoint.ToString().IndexOf("6666") != -1)
                {
                    int NewPid = PID++;
                    localPort = NewPid;
                    AcceptConnection();
                    SendData(System.Text.Encoding.Default.GetBytes("PID|" + NewPid), workerSocket);
                }
                else
                { 
                    //存储客户端sokect
                    clientList.Add(workerSocket);
                    listBox1.Invoke(slist, workerSocket.RemoteEndPoint.ToString());
                }
                mainSocket.BeginAccept(new AsyncCallback(AcceptCallBack), mainSocket);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        public void SendData(byte[] buffer, Socket workerSocket)
        {
            try
            {
                int left = buffer.Length;
                int sndLen = 0;
                workerSocket.BeginSend(buffer, sndLen, left, SocketFlags.None, new AsyncCallback(SendCallBack), workerSocket);
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void SendCallBack(IAsyncResult iar)
        {
            Socket workerSocket = (Socket)iar.AsyncState;
            workerSocket.EndSend(iar);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            byte[] buffer=System.Text.Encoding.Default.GetBytes("mesg|"+textBox1.Text);
            int snLen=0;
            listBox2.Items.Add(textBox1.Text);
            while(true)
            for (int i = 0; i < clientList.Count; i++)
            {
                int k = i;
                Thread aa = new Thread(new ThreadStart(()=> 
                {
                    ((Socket)clientList[k]).BeginSend(buffer, snLen, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), ((Socket)clientList[k]));
                }));
                aa.IsBackground = true;
                aa.Start();   
            }
        }
    }
}
客户端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace 多端口客户端
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label = (text,la) =>
            {
                la.Text = text;
            };
            slist = aa =>
            {
                listBox1.Items.Add(aa);  
            };
        }
        private int serverPort = 6666;
        public byte[] dataBuffer = new byte[10000000];
        private Socket client;
        private delegate void setLabel(string text,Label la);
        private setLabel label;
        private delegate void SetListBoxCallBack(string str);
        private SetListBoxCallBack slist;
        private void button1_Click(object sender, EventArgs e)
        {
            ServerConnection();
        }
        //连接服务器
        private void ServerConnection()
        {
            try
            {
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.169.1.113"), serverPort);
                client = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(ipEndPoint);
                label1.Invoke(label, client.RemoteEndPoint.ToString(),label1);
                label2.Invoke(label, client.LocalEndPoint.ToString(), label2);
                client.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), client);
            }
            catch (Exception ex)
            {
                throw;
            }

        }
        //回调接收函数
        private void RecieveCallBack(IAsyncResult iar)
        {
            Socket socketData = (Socket)iar.AsyncState;
            int iRx = socketData.EndReceive(iar);
            string revStr = System.Text.Encoding.Default.GetString(dataBuffer, 0, iRx);
            string[] str = revStr.Split('|');
            if (str[0] == "PID")
            {
                serverPort =Convert.ToInt32(str[1]);
                ServerConnection();
            }
            if (str[0] == "mesg")
            {
                listBox1.Invoke(slist, str[1]);
                socketData.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), socketData);
            }
           
        }
    }
}

posted on 2010-04-08 14:49  大狼熙熙  阅读(7360)  评论(3编辑  收藏  举报