首先,我不知道Stackoverflow是否是发布此类消息的最佳网站,但我不知道这样的其他网站.
为了在C#中正确理解tcp编程,我决定从头开始做所有可能的方法.这是我想知道的(不是正确的顺序: - 简单的一个线程套接字服务器(本文) - 简单的多线程套接字服务器(我不知道如何,导致线程复杂) - 简单的线程套接字服务器(放另一个线程中的客户端管理) - 多线程套接字服务器 - 使用tcpListener - 使用async/Await - 使用任务最终目标是知道如何做最好的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());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我对此有一些疑问:
来自Socket的Listen方法有一个参数:backlog.根据MSDN,积压是可用连接的数量.我不知道为什么,当我把0,我可以通过多个Telnet会话连接到我的服务器.编辑:0和1都允许2个连接(1个电流,1个待处理),2个允许3个连接(1个电流,2个待处理)等...所以我不太了解MSDN的含义.
你能否确认Accept Method将逐个接受每个连接,这就是为什么我在服务器中看到来自不同Telnet会话的文本?
你能确认一下(我的服务器是一个C#库)我不能杀死我的服务器(使用这种代码)而不会杀死进程吗?它可以用线程,但它会在以后出现.
如果我的代码出了问题,请帮帮我:)
我将很快回来使用一个简单的多线程套接字服务器,但我不知道如何(我认为在使用线程或async/await之前一步可用).
首先,尽量不要学习这一点.如果您可以使用SignalR服务器,那么请执行此操作.有没有这样的事情是在TCP/IP级"简单"套接字服务器.
如果你坚持痛苦的路线(即学习正确的TCP/IP服务器设计),那么有很多东西需要学习.首先,MSDN示例是众所周知的糟糕起点; 它们几乎不能工作,往往不能处理任何类型的错误条件,这在现实世界中在TCP/IP级别工作时是绝对必要的.可以将它们视为如何调用方法的示例,而不是套接字客户机或服务器的示例.
我有一个可能对您有帮助的TCP/IP常见问题,包括backlog参数说明.这是操作系统在您的代码接受它们之前代表您接受的连接数,并且它只是一个提示.
回答您的其他问题:单个呼叫Accept将接受单个新的套接字连接.写入的代码具有无限循环,因此它将像任何其他无限循环一样工作; 它将继续执行,直到遇到异常或其线程中止(在进程关闭时发生).
如果我的代码出了问题,请帮助我
哦,是的.这段代码有很多问题.毕竟,这是一个MSDN套接字示例.:)脱离我的头顶:
Bind明确使用回送地址.我想,可以玩,但请记住IPAddress.Any在现实世界中设置它.backlog参数可以用于测试,但应该int.MaxValue在真正的服务器上以启用现代服务器操作系统中的动态积压.catch并尝试Accept在Bind/ Listen失败之后.Listen或Receive),则整个服务器将关闭.请注意,终止的客户端套接字将导致应记录/忽略的异常,但它会停止此服务器.<EOF>,则服务器进入无限繁忙的循环.那只是在简短的阅读之后.可能会有更多.
| 归档时间: |
|
| 查看次数: |
1683 次 |
| 最近记录: |