基本思路是:
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); } } } }