1、使用VS创建类库(使用的是框架类库),跟着创建一个控制台程序用来开启服务器,这里要添加类库的引用。
2、在类库下创建一个服务器类用作服务端使用,创建服务器端的Socket对象//using System.Net.Sockets;
/// <summary>
/// 服务器端的Socket对象
/// </summary>
private Socket serverSocket;
// serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
3、把开启服务器的封装在Start方法里,网络多用捕捉异常来避免出现问题。
/// <summary>
/// 用来开启服务器
/// </summary>
/// <param name="port">端口号</param>
/// <param name="maxCount">最大连接数量</param>
public void Start(int port, int maxCount)
{
try
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Listen(maxCount);//多少都可以,之后用流量来限制
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
4、在控制台程序中调用Start方法
server.Start(6666, 10);
//尽量的把单独的功能提取为单独的方法,看起来整齐后期好维护
5、 使用异步等待客户端连接,多线程的使用防止服务器出现问题
/// <summary>
/// 开始等待客户端的连接/// </summary>
/// <param name="e"></param>
private void StartAccept(SocketAsyncEventArgs e)
{
if (e==null)
{
e = new SocketAsyncEventArgs();
e.Completed += Accept_Complete;
}
bool result = serverSocket.AcceptAsync(e);//如果返回True,表示还在执行处理的进程,false就是处理完成了
if (result==false)
{
ProcessAccept(e);
}
}
6、 得到客户端对象,处理客户端与服务器之间的发送和接收。给处理完连接注册事件。
/// <summary>
/// 接收连接请求异步事件完成时触发/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Accept_Complete(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
/// <summary>
/// 处理连接请求
/// </summary>
/// <param name="e"></param>
private void ProcessAccept(SocketAsyncEventArgs e)
{
//得到对象
Socket clientSocket = e.AcceptSocket;
//再进行保存处理
//TODO
}
7、当要接受连接时,之后限制可访问的线程数,using System.Threading;下Semaphore 的WaitOne函数,用来等待连接的线程,比如说总共可以连接10个,次函数会从0加到9 然后等待,不会多加,只会有退出留下空余再加。
/// <summary>/// 限制可同时访问资源的线程数
/// </summary>
private Semaphore acceptSemaphore;
在此处使用:
/// <summary>
/// 开始等待客户端的连接
/// </summary>
/// <param name="e"></param>
private void StartAccept(SocketAsyncEventArgs e)
{
if (e==null)
{
e = new SocketAsyncEventArgs();
e.Completed += Accept_Complete;
}
//限制线程的访问
acceptSemaphore.WaitOne();
bool result = serverSocket.AcceptAsync(e);//如果返回True,表示还在执行处理的进程,false就是处理完成了
if (result==false)
{
ProcessAccept(e);
}
}