Ответ 1
ListenForClients
вызывается дважды (на двух разных потоках) - один раз из конструктора, один раз из явного вызова метода в Main
. Когда два экземпляра TcpListener
пытаются прослушивать один и тот же порт, вы получаете эту ошибку.
Я сделал много поисковых запросов, но мне не повезло с моими проблемами. Я новичок в сетевом программировании и стараюсь учиться, я попытался настроить простой сервер и клиент, которые общаются (после онлайн-учебника, расположенного здесь → http://tech.pro/tutorial/704/csharp-tutorial-simple-threaded-tcp-server)
Проблема, с которой я столкнулась, заключается в том, что я продолжаю получать исключение. "При попытке запустить TcpListener на сервере обычно разрешается использовать только одно использование каждого адреса сокета (протокол/сетевой адрес/порт).
Я попытался отключить мой брандмауэр, изменив используемый порт, перемещая переменные, но безрезультатно (клиент работает нормально, но он, очевидно, не может найти сервер, потому что я не могу его запустить).
Я видел решения, описывающие использование Socket.Poll(), но поскольку я использую только объект TcpListener, я понятия не имею, как использовать функцию опроса.
Мой код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
namespace ServerTutorial {
class Server {
private readonly Thread m_listenThread;
public Server() {
m_listenThread = new Thread(new ThreadStart(ListenForClients));
m_listenThread.Start();
}
public void ListenForClients() {
var listener = new TcpListener(IPAddress.Any, 3000);
listener.Start();
while (true) {
//Blocks until a client has connected to the server
TcpClient client = listener.AcceptTcpClient();
//Send a message to the client
var encoder = new ASCIIEncoding();
NetworkStream clientStream = client.GetStream();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
//Create a thread to handle communication with the connected client
var clientThread = new Thread(new ParameterizedThreadStart(HandleClient));
clientThread.Start(client);
}
}
private void HandleClient(object clientObj) { //Param thread start can only accept object types, hence the cast
var client = (TcpClient) clientObj;
NetworkStream clientStream = client.GetStream();
var message = new byte[4096];
while (true) {
int bytesRead = 0;
try {
//Block until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
} catch {
//A socket error has occurred
System.Diagnostics.Debug.WriteLine("A socket error has occured");
break;
}
if (bytesRead == 0) {
//The client has disconnected from the server
System.Diagnostics.Debug.WriteLine("A client has disconnected from the server");
client.Close();
break;
}
//Message has been received
var encoder = new ASCIIEncoding();
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
}
}
}
}
В моем основном методе:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerTutorial {
class Program {
static void Main(string[] args) {
var server = new Server();
server.ListenForClients();
}
}
}
Любая помощь очень ценится!
ListenForClients
вызывается дважды (на двух разных потоках) - один раз из конструктора, один раз из явного вызова метода в Main
. Когда два экземпляра TcpListener
пытаются прослушивать один и тот же порт, вы получаете эту ошибку.
Вы отлаживаете два или более раз. поэтому приложение может работать больше за раз. Тогда будет только эта проблема. Вы должны закрыть все приложения для отладки с помощью диспетчера задач, затем снова отлаживать.