我用C#建立了一个服务器,在程序关闭的时候,程序不能完全关闭,代码如下: public void Stop()
{//停止服务器
try
{
if (tmpSocket!=null)
{
tmpSocket.Close();
}
if (serverThread!=null)
{
serverThread.Abort();
}
if (clientService!=null)
{
clientService.Abort();
}
listener.Stop();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
请大虾指教
{//停止服务器
try
{
if (tmpSocket!=null)
{
tmpSocket.Close();
}
if (serverThread!=null)
{
serverThread.Abort();
}
if (clientService!=null)
{
clientService.Abort();
}
listener.Stop();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
请大虾指教
{
Console.WriteLine(ex.ToString());
} 不过在结束程序的时候出现
你这个tmpSocket估计就是子线程中用的socket吧?
你这个close只能关闭最后一次连接的socket,以前连接的都没办法关闭。。
另外对线程使用abort的时候在线程中最好这样捕捉一下错误
执行abort时回抛出一个ThreadAbortException
catch (ThreadAbortException)
{
return;
}
关于多个子线程中的socket控制可以用一个list<socket>进行控制。。我以前问过phy 一个问题,里面有一个简单的多线程的例子,当然那个代码有点问题,但是对socket的控制还是对的那个是vs2003的用的arraylist,2003之后的版本最好用list<socket>
http://topic.csdn.net/u/20080916/14/0c8c7f17-7a4d-449b-bcc8-6be33b106101.html关键还是要看看你的代码具体是怎么写的
另外listener.Stop();
只是停止监听,不释放资源
{//服务器端,以后还是仔细完善
private int portNum = 1234;
private int buff_length;
private TcpListener listener;
protected Thread serverThread;
private Socket tmpSocket;
//服务器可以支持的最多的客户端的连接数
private static int MaxNum = 100;
//clients数组保存当前在线用户的Client对象
private static ArrayList clients = new ArrayList();
private IPAddress localIP;
private bool startServer; private byte[] recvBuff = null;
private byte[] sendBuff = null; //设置一个回调函数供其它客户调用
TcpEventProc eventProc;
Thread clientService; bool keepalive = true;
bool keepConnect = true; public NetworkTcpServer()
{
startServer = true;
buff_length = 100;
recvBuff = new byte[100];
sendBuff = new byte[100];
} public void SetEventProc(TcpEventProc process)
{
this.eventProc = process;
} public void Start(int port)
{//启动服务器
try
{
if(startServer)
{
//创建服务器套接字
listener = new TcpListener(IPAddress.Any, port);
//开始监听服务器端口
listener.Start();
//启动一个新的线程,执行方法this.StartListen,以便在一个独立的进程
//中执行确认与客户端连接的操作
serverThread = new Thread(new ThreadStart(this.StartListen));
serverThread.Start();
startServer = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
} public void Stop()
{//停止服务器
startServer = true;
keepalive = false;
keepConnect = false; try
{
if (tmpSocket!=null)
{
tmpSocket.Close();
}
if (serverThread!=null)
{
serverThread.Abort();
}
if (clientService!=null)
{
clientService.Abort();
}
listener.Stop();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
} private void StartListen()
{//开始启动监听是否有客户端的连接请求
while (keepalive)
{
try
{
//当接收到一个客户端请求时,确认与客户端的连接
Socket socket = listener.AcceptSocket();
//用tmpSocket保存发出请求的客户端实例
tmpSocket = socket;
if (clients.Count >= MaxNum)
{
tmpSocket.Close();
}
else
{
// 启动一个新的线程,执行方法this.ServiceClient,处理用户相应的请求
clientService = new Thread(new ThreadStart(this.ServiceClient));
clientService.Start();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
private void ServiceClient()
{//此线程用于接收客户端发送过来的数据,同时与客户端进行数据交流
Socket clientSocket = tmpSocket;
//用循环来不断地与客户端进行交互,直到客户端发出“EXIT”命令,将keepConnect置为false,退出循环,
//关闭连接,并中止当前线程
while (keepConnect)
{
////接收数据并存入buff数组中
try
{
//NetworkStream cliendStream=clientSocket.;
//cliendStream.Read(recvBuff, 0, 100);
int length = clientSocket.Receive(recvBuff);
//将字符数组转化为字符串
string clientCommand = System.Text.Encoding.ASCII.GetString(recvBuff);
eventProc(clientCommand);
}
catch (System.Exception e)
{
}
}
}部分代码如上所示
private Dictionary<string, Thread> m_DTThreads = new Dictionary<string, Thread>(Max_LinkCount);控制线程关闭的时候遍历一遍list<socket>,将里面的socket全部关闭,
并且将对应线程abort和join,abort的错误要捕捉。。另外你这样控制客户端的连接数不太好
我给你的建议是将
//开始监听服务器端口
listener.Start();
放到主线程中,当连接数达到的时候将listener.stop();
然后当不满的时候又listener.Start(); 这是个思路具体的代码我就不写了(当然对多线程的控制也可以用threadpool)
给你个关闭的例子,希望对你有启发
public void StopServer()
{
try
{
Monitor.Enter(this);
//子线程的循环用的
SubThreadLoopFlag = false;
//主线程序循环用的
MainThreadLoopFlag = false;
if (MainThread != null)
{ if (ServerSock != null)
{
string sIP = "";
//这里遍历一遍连接的socket
for (int i = m_listSockets.Count - 1; i >= 0; i--)
{
Socket sock = null;
IPEndPoint ipe = null;
Thread tempT = null; sock = (Socket)(m_listSockets[i]);
if (sock != null)
{
ipe = (IPEndPoint)(sock.RemoteEndPoint);
sIP = ipe.ToString();
string sKey = ipe.Address.ToString() + ":" + ipe.Port.ToString();
//关闭对应的子线程
tempT = (Thread)m_DTThreads[sKey];
try
{
if (tempT.IsAlive)
tempT.Abort();
if (sock.Connected)
{
sock.Shutdown(SocketShutdown.Both);
(ipe.Address.ToString(), ipe.Port);
}
sock.Close();
sock = null;
tempT.Join();
tempT = null;
}
catch (Exception ex)
{
}
}
}
ServerSock.Close();
}
//关闭主线程和TcpListener
MainThread.Abort();
ServerTcpL.Stop();
MainThread.Join();
MainThread = null;
}
}
catch (Exception ex)
{
}
finally
{
ServerSock = null;
//清空list和Dictionary
m_listSockets.Clear();
m_DTThreads.Clear();
ConnectCount = 0;
Monitor.Exit(this);
}
}