我在服务器上监听10端口,给每个端口分配一个线程,
可是每次一个端口只能监听到第一个客户端,以下的客户端能连接上,但服务器监听不到,很是郁闷!
那位大哥帮帮小弟!!
for (int i = 0; i < 10; i++)
{
scon = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Svr = new IPEndPoint(SvrIP, IntPort[i]);
scon.Bind(Svr);
scon.Listen(100);
SvrListenThread[i]= new Thread(ListenThread);
SvrListenThread[i].Start();
Thread.Sleep(100);
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message.ToString()); }
}
#endregion
//'侦听线程
private void ListenThread()
{
try
{
while (true)
{
//Done.Reset()
//'开始一个异步操作来接受一个传入的连接尝试
IAsyncResult ar;
ar = scon.BeginAccept(new AsyncCallback(AcceptCallback), scon);
ar.AsyncWaitHandle.WaitOne();
}
}
catch (SocketException)
{
//MsgBox(ex.Message.ToString); }
}
可是每次一个端口只能监听到第一个客户端,以下的客户端能连接上,但服务器监听不到,很是郁闷!
那位大哥帮帮小弟!!
for (int i = 0; i < 10; i++)
{
scon = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Svr = new IPEndPoint(SvrIP, IntPort[i]);
scon.Bind(Svr);
scon.Listen(100);
SvrListenThread[i]= new Thread(ListenThread);
SvrListenThread[i].Start();
Thread.Sleep(100);
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message.ToString()); }
}
#endregion
//'侦听线程
private void ListenThread()
{
try
{
while (true)
{
//Done.Reset()
//'开始一个异步操作来接受一个传入的连接尝试
IAsyncResult ar;
ar = scon.BeginAccept(new AsyncCallback(AcceptCallback), scon);
ar.AsyncWaitHandle.WaitOne();
}
}
catch (SocketException)
{
//MsgBox(ex.Message.ToString); }
}
{
try
{
//Done.Reset()
//'开始一个异步操作来接受一个传入的连接尝试
scon.BeginAccept(new AsyncCallback(AcceptCallback), scon);
}
catch (SocketException)
{
//MsgBox(ex.Message.ToString); }
}
//加这个过程
private void AcceptCallback(IAsyncResult args)
{
Socket _socketListener = (Socket)args.AsyncState;
Socket _socket = _socketListener.EndAccept(args);
scon.BeginAccept(new AsyncCallback(AcceptCallback), scon);
//下方就可以处理你的数据了,当前可操作的Socket为_socket
}
这个有问题.
private void AcceptCallback(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
try
{
StateObject Tate = new StateObject();
Tate.workSocket = handler;
handler.BeginReceive(Tate.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), Tate);
}
catch (SocketException)
{
//MsgBox(ex.Message.ToString) } }
本人已基本想出解决限制客户端的连接数的方法,但是出现一个问题就是明明我是设置只允许连接N个,却可以连接N+1个,但第N+2个时就会失败,我没查出原因。
我的代码如下:
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;
using System.Threading;
namespace TCPSERVER
{
public partial class FrmServer : Form
{
private Socket m_ServerListener = null;
private ClientInformationCls[] m_clientList;
delegate void SetTextCallback(string strText);
private const int MAX_CLIENT = 1; //client connnecting max number public FrmServer()
{
InitializeComponent();
} private static IPAddress GetServerIP()
{ IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName()); return ieh.AddressList[0]; } private void BeginListen()
{
int intPort =8000; m_clientList=new ClientInformationCls[ MAX_CLIENT ]; IPAddress ServerIp = GetServerIP(); IPEndPoint iep = new IPEndPoint(ServerIp, intPort);
m_ServerListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_ServerListener.Bind(iep);
m_ServerListener.Listen(1);
} private void btnBeginListen_Click(object sender, EventArgs e)
{
try
{
BeginListen();
lstServerStatus.Items.Add("Server is starting listening...."); InitClientList(); Thread acceptThread = new Thread(new ThreadStart(AcceptClientThread));
acceptThread.Start();
}
catch (SocketException ex)
{
MessageBox.Show(ex.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} private void AcceptClientThread()
{
int intClientIndex; Thread.CurrentThread.IsBackground = true; try
{
while (true)
{
intClientIndex = GetFreeClient();
if (intClientIndex != -1)
{
m_clientList[intClientIndex].IsIdle = false;
Socket clientSocket = m_ServerListener.Accept();
IPEndPoint remoEP = (IPEndPoint)clientSocket.RemoteEndPoint;
m_clientList[intClientIndex].ClientIP = remoEP.Address.ToString();
m_clientList[intClientIndex].ClientSocket = clientSocket;
SetText("connecting from " + m_clientList[intClientIndex].ClientIP); Thread DealingThread = new Thread(new ParameterizedThreadStart(RcvSndThread)); DealingThread.Start(m_clientList[intClientIndex]); }
}
} catch (SocketException ex)
{
MessageBox.Show(ex.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
} } private void RcvSndThread(object obj)
{
Thread.CurrentThread.IsBackground = true;
ClientInformationCls clientTmp = (ClientInformationCls)obj;
byte[] buffer = new byte[1024];
int intRcvCount; try
{
while (clientTmp.ClientSocket.Connected == true)
{
intRcvCount = clientTmp.ClientSocket.Receive(buffer);
SetText(Encoding.Default.GetString(buffer, 0, intRcvCount)); }
} catch (SocketException ex)
{
MessageBox.Show(ex.ToString());
} catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} private void InitClientList()
{
int i = 0;
for (i=0; i <= m_clientList.Length-1; i++)
{
m_clientList[i] = new ClientInformationCls();
m_clientList[i].ClientHostName="";
m_clientList[i].ClientIP = "";
m_clientList[i].Index=i;
m_clientList[i].IsIdle = true;
m_clientList[i].ClientSocket = null;
}
} private int GetFreeClient()
{
int i = 0;
for (i = 0; i <= m_clientList.Length - 1; i++)
{
if (m_clientList[i] == null) return -1;
if (m_clientList[i].IsIdle == true)
{
return i;
}
}
return -1;
} private void SetText(string strText)
{
if (this.lstServerStatus.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { strText });
}
else
{
this.lstServerStatus.Items.Add(strText);
}
} }
}
其中 ClientInformationCls是本人自定义的类,一个保存客户端SOCKET的连接信息,其中有个IsIdle属性用来记录该SOCKET是否可用
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace TCPSERVER
{
class ClientInformationCls
{
private int m_intClientIndex; //client's index
private string m_strClientIP;
private string m_strClientHostName;
private bool m_blnIsIdle;
private Socket m_clientSocket;
public int Index
{
get{return m_intClientIndex;}
set{m_intClientIndex=value;}
} public string ClientIP
{
get { return m_strClientIP; }
set { m_strClientIP = value; }
} public string ClientHostName
{
get { return m_strClientHostName; }
set { m_strClientHostName = value; }
} public bool IsIdle
{
get { return m_blnIsIdle; }
set { m_blnIsIdle = value; }
}
public Socket ClientSocket
{
get { return m_clientSocket; }
set { m_clientSocket = value; }
}
}
} 我在AcceptClientThread函数中调用了
intClientIndex = GetFreeClient();
如果intClientIndex=-1的话表示不能在允许其他的客户端连接,这样就不会创建新的线程了,
现在我的问题是我明明创建了数组 m_clientList=new ClientInformationCls[ MAX_CLIENT ];
而MAX_CLIENT初始化时已经设置为1了,也就是说服务端最大的连接数为MAX_CLIENT=1,
而我测试的时候,服务端最大的连接数为MAX_CLIENT+1了,请高手帮忙看看