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