Здравствуйте, пишу класс сервера, который мог бы обрабатывать несколько подключений. До этого никогда не писал. Использую TcpListener и TcpClient. После запуска TcpListener, каждое новый TcpClient сохраняется и в нём вызывается метод BeginRead, который, по-моему пониманию, будет ждать, пока на другом конце я не запишу строку в буфер, например, с помощью Write. Однако, работает не так, как ожидалось. BeginRead бесконечно считывает пустые строки, а при попытке выполнения Read со стороны клиента происходит ошибка: "Операция не разрешается на не подключённых сокетах" Совсем не понятно почему, ведь успешно выполнил команду Connect
и не отключался.
Этот метод запускается в процессе сервера
public void Start()
{
try
{
TcpListener tcpListener = new TcpListener(IPAddress.Parse(ipAddress), port);
tcpListener.Start();
ServerLogger.Log("Server has been started");
while(true)
{
GameConnections.Add(new GameConnection(tcpListener.AcceptTcpClient(), GameConnections.Count));
}
}
catch(Exception ex)
{
ServerLogger.Error(ex.Message);
}
}
Создание подключения
class GameConnection
{
string GameID { get; set; }
string ConnectionID { get; set; }
TcpClient Client { get; set; }
byte[] acceptedData = new byte[1024];
byte[] sendData = new byte[1024];
byte[] buffer = new byte[1024];
NetworkStream stream;
public GameConnection(TcpClient client, int id)
{
Client = client;
stream = client.GetStream();
ConnectionID = "connection" + id;
ServerLogger.Log(string.Format("Client connected. ConnectionID: {1}", GameID, ConnectionID));
stream.BeginRead(acceptedData, 0, acceptedData.Length, FirstReadCallback, null);
}
public void FirstReadCallback(IAsyncResult ar)
{
int bytesRead = stream.EndRead(ar);
if(bytesRead > 0)
{
Console.WriteLine(bytesRead);
GameID = Encoding.UTF8.GetString(acceptedData, 0, bytesRead);
Console.WriteLine("Game id - " + GameID);
stream.BeginRead(acceptedData, 0, acceptedData.Length, ReadCallback, null);
ServerLogger.Log(String.Format("{0} game id is {1}", ConnectionID, GameID));
}else
{
ServerLogger.Log(String.Format("Empty first read from client({0})", ConnectionID));
stream.BeginRead(acceptedData, 0, acceptedData.Length, FirstReadCallback, null);
}
}
public void ReadCallback(IAsyncResult ar)
{
int bytesRead = stream.EndRead(ar);
if(bytesRead > 0)
{
string command = Encoding.UTF8.GetString(acceptedData, 0, bytesRead);
ServerLogger.Log(String.Format("Command from client({0}): {1}", ConnectionID, command));
string serverAnswer = "some game command";
Encoding.UTF8.GetBytes(serverAnswer, 0, serverAnswer.Length, sendData, 0);
stream.BeginWrite(sendData, 0, sendData.Length, WriteCallback, null);
}else
{
ServerLogger.Log(String.Format("Empty read from client({0})", ConnectionID));
stream.BeginRead(acceptedData, 0, acceptedData.Length, ReadCallback, null);
}
}
public void WriteCallback(IAsyncResult ar)
{
stream.EndWrite(ar);
stream.BeginRead(acceptedData, 0, acceptedData.Length, ReadCallback, null);
}
После того как сервер запущен пробую подключиться так:
static void Main(string[] args)
{
TcpClient client = new TcpClient();
try
{
Console.WriteLine("Connecting to server");
client.Connect(IPAddress.Parse("127.0.0.1"), 8888);
using (BinaryWriter writer = new BinaryWriter(client.GetStream()))
{
byte[] data = new byte[1024];
string gameID = "1000";
Encoding.UTF8.GetBytes(gameID, 0, gameID.Length, data, 0);
writer.Write(data, 0, gameID.Length);
Console.WriteLine(Encoding.UTF8.GetString(data));
}
while (true)
{
string command = Console.ReadLine();
if (command == "exit") break;
byte[] data = new byte[1024];
NetworkStream stream = client.GetStream();
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(command);
}
using (BinaryReader reader = new BinaryReader(stream))
{
reader.Read(data, 0, 1024);
Console.WriteLine("Server answer: {0}", Encoding.UTF8.GetString(data));
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
client.Close();
}
}
По итогу в лог выглядит так:
Server has been started
Client connected. ConnectionID: connection0
connection0 game id is 1000
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Empty read from client(connection0)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Делаю модуль на сайте, который выводит пользователей на сайте за последние 24 часаВключил <anonymousIdentification enabled="true" /> на сайте
Не понимаю как правильно сделать чекбокс на показ пароля если отмеченЕсть вот такой код
Назначение Программа реализует автоматный распознаватель, использующий в качестве структуры данных таблицу переходов