Во-первых, я не знаю, является ли Stackoverflow лучшим сайтом для публикации такого сообщения, но я не знаю других сайтов, подобных этому.Simple One Thread Socket - TCP-сервер
Чтобы понять правильную программирование tcp в C#, я решил сделать все возможное с нуля. Вот что я хочу знать (не в правильном порядке: - Simple One Thread Socket Server (эта статья) - Простой многопоточный сервер Socket (я не знаю, как, потому что потоки сложны) - Простая резьба сервер (поставить управление клиентом в другом потоке) - несколько потоков сокеты сервера - Использование TcpListener - Использование асинхронного/ОЖИДАНИИ - Использование задач конечная цель состоит в том, чтобы знать, как сделать лучший сервер TCP, не просто копировать/вставить некоторые части прибывают, но все правильно понимают.
Итак, это моя первая часть: один поток tcp-сервера.
Существует мой код, но я не думаю, что кто-то будет что-то исправить, потому что это довольно копия MSDN: http://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace SimpleOneThreadSocket
{
public class ServerSocket
{
private int _iPport = -1;
private static int BUFFER_SIZE = 1024;
private Socket _listener = null;
public ServerSocket(int iPort)
{
// Create a TCP/IP socket.
this._listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Save the port
this._iPport = iPort;
}
public void Start()
{
byte[] buffer = null;
String sDatasReceived = null;
// Bind the socket to loopback address
try
{
this._listener.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, _iPport));
this._listener.Listen(2);
}
catch (Exception e)
{
System.Console.WriteLine(e.ToString());
}
// Listening
try
{
Console.WriteLine("Server listening on 127.0.0.1:" + _iPport);
while (true)
{
Socket client = this._listener.Accept();
Console.WriteLine("Incoming connection from : " + IPAddress.Parse(((IPEndPoint)client.RemoteEndPoint).Address.ToString()) + ":" + ((IPEndPoint)client.RemoteEndPoint).Port.ToString());
// An incoming connection needs to be processed.
while (true)
{
buffer = new byte[BUFFER_SIZE];
int bytesRec = client.Receive(buffer);
sDatasReceived += Encoding.ASCII.GetString(buffer, 0, bytesRec);
if (sDatasReceived.IndexOf("<EOF>") > -1)
{
// Show the data on the console.
Console.WriteLine("Text received : {0}", sDatasReceived);
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(sDatasReceived);
client.Send(msg);
sDatasReceived = "";
buffer = null;
}
else if (sDatasReceived.IndexOf("exit") > -1)
{
client.Shutdown(SocketShutdown.Both);
client.Close();
sDatasReceived = "";
buffer = null;
break;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Но у меня есть несколько вопросов о том, что:
Listen Метод из Socket имеет параметр: backlog. Согласно MSDN, отставание - это количество доступных соединений. Я не знаю, почему, когда я ставлю 0, я могу подключиться к моему серверу с несколькими сеансами Telnet. EDIT: 0 & 1 оба разрешают 2 соединения (1 текущий, 1 незавершенный), 2 позволяют 3 соединения (1 текущий, 2 ожидающих ожидания) и т. Д. Поэтому я не очень хорошо понял смысл MSDN.
Можете ли вы подтвердить, что метод Accept будет принимать каждое соединение один за другим, поэтому я вижу текст из разных сеансов Telnet на моем сервере?
Можете ли вы подтвердить (мой сервер является библиотекой C#) Я не могу убить мой сервер (с помощью такого кода), не убивая процесс? Это возможно с помощью потоков, но это произойдет позже.
Если что-то не так в моем коде, пожалуйста, помогите мне :)
Я скоро вернусь с простым множественным сервером сокета поток, но я не знаю, как (я думаю, что один шаг доступный перед использованием потоков или async/await).
Любовь необъяснимых downvotes. Кто-нибудь хочет высказаться? Вы знаете, на самом деле указывают на один неверный момент в моем ответе? ;) –
Бог, это код на MSDN? Это должно отвечать за часть многих вопросов TCP, на которые я отвечаю. – usr
@usr: Я серьезно планирую сделать серию блога, разрывая примеры сокетов MSDN, по одному сообщению на образец. Шаг за шагом, объясняя, почему это неправильно, и как это сделать правильно. Кстати, исходный пример MSDN еще хуже (привязывается к 'Dns.Resolve (Dns.GetHostName())) ... Но я планировал эту серию блога годами; не стесняйтесь принимать эту идею и бегать с ней! :) –