当客户端断开连接时,服务器将关闭。告诉我如何在第一次会议结束后留下连接新客户的能力。提前谢谢。
namespace tcpserver
{
class Program
{
static void Main(string[] args)
{
string cmd;
int port = 56568;
Server Serv = new Server(); // Создаем новый экземпляр класса
// сервера
Serv.Create(port);
while (true)
{
cmd = Console.ReadLine(); // Ждем фразы EXIT когда
// понадобится выйти из приложения.
// типа интерактивность.
if (cmd == "EXIT")
{
Serv.Close(); // раз выход – значит выход. Серв-нах.
return;
}
}
//while (Serv.Close() == true) { Serv.Create(port); }
}
public class Server // класс сервера.
{
private int LocalPort;
private Thread ServThread; // экземпляр потока
TcpListener Listener; // листенер))))
public void Create(int port)
{
LocalPort = port;
ServThread = new Thread(new ThreadStart(ServStart));
ServThread.Start(); // запустили поток. Стартовая функция –
// ServStart, как видно выше
}
public void Close() // Закрыть серв?
{
Listener.Stop();
ServThread.Abort();
return;
}
private void ServStart()
{
Socket ClientSock; // сокет для обмена данными.
string data;
byte[] cldata = new byte[1024]; // буфер данных
Listener = new TcpListener(LocalPort);
Listener.Start(); // начали слушать
Console.WriteLine("Waiting connections on " + Convert.ToString(LocalPort) + " port");
try
{
ClientSock = Listener.AcceptSocket(); // пробуем принять клиента
}
catch
{
ServThread.Abort(); // нет – жаль(
return;
}
int i = 0;
if (ClientSock.Connected)
{
while (true)
{
try
{
i = ClientSock.Receive(cldata); // попытка чтения
// данных
}
catch
{
}
try
{
if (i > 0)
{
data = Encoding.ASCII.GetString(cldata).Trim();
Console.WriteLine("<" + data);
if (data == "CLOSE") // если CLOSE –
// вырубимся
{
ClientSock.Send(Encoding.ASCII.GetBytes("Closing the server..."));
ClientSock.Close();
Listener.Stop();
Console.WriteLine("Server closed. Reason: client wish! Type EXIT to quit the application.");
ServThread.Abort();
return;
}
else
{ // нет – шлем данные взад.
ClientSock.Send(Encoding.ASCII.GetBytes("Your data: " + data));
}
}
}
catch
{
ClientSock.Close(); //
Listener.Stop();
Console.WriteLine("Client disconnected. Server closed.");
ServThread.Abort();
}
}
}
}
}
}
}
答案 0 :(得分:3)
典型的线程服务器代码将更像这样(在伪代码中,因为我不知道足够的Java细节来准确地写它,并且因为C有点令人窒息):
socket s = new socket
bind s to an optional IP, port
listen s
while true
cli = accept s
t = new thread(handle_client, cli)
maybe disown thread, so no need to join it later
t.start
重要的一点是,创建套接字,将其绑定到一个地址,listen
都在循环外部处理,而accept()
和起始线程是内部循环。
您可能希望将整个块包装在另一个线程中;这是可以接受的。重要的是将listen
与accept
和每个客户thread
分开。这允许您的代码停止接受新连接,但处理现有客户端,直到它们断开连接,或在使用分配资源但仍继续接受连接等时断开现有连接。(注意您的上一个catch
块将如何终止服务器如果任何单个客户端套接字抛出异常;使用通常的服务器布局很容易避免这种代码。)
答案 1 :(得分:2)
替换
ServThread.Abort();
return;
使用continue,这不会破坏while循环,但会停止当前的“round”。请考虑阅读:http://www.codeproject.com/KB/IP/serversocket.aspx从
构建的好项目