///
///编写服务器
///
namespace Server
{
class ServerMain
{
public Client_side[] clients;//客户端连接池
public Socket listen;//监听套接字
public int maxClient = 26;//最大连接数
//判断客户端是否连接成功 正数为连接成功 负数为连接失败
public int NewIndex()
{
//获取连接池,返回负数代表连接失败或是未连接
if (clients == null)
{
return -1;
}
for (int i = 0; i < clients.Length; i++)
{
if (clients[i] == null)
{
//实例化客户端(就是给客户端赋好值)
clients[i] = new Client_side();
return i;
}
else if (clients[i].isside == true)
{
return i;
}
}
return -1;
}
/// <summary>
/// 开启服务器
/// </summary>
/// <param name="ip">地址</param>
/// <param name="port">端口号</param>
public void Connection(string ip, int port)
{
//实例化连接池 长度为最大连接数
clients = new Client_side[maxClient];
//实例化客户端
for (int i = 0; i < maxClient; i++)
{
clients[i] = new Client_side();
}
//实例化socket//IPv6比IPv4安全 //UDP时时更新,但容易丢失数据(用来开视频语音聊天)
listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//下面两行代码意思就只是赋值
IPAddress _IP = IPAddress.Parse(ip);//IP地址6
//获取端口号和IP地址
IPEndPoint connect = new IPEndPoint(_IP, port);
//绑定端口号和IP地址
listen.Bind(connect);
//监听
listen.Listen(maxClient);
//创建新的连接
listen.BeginAccept(NewConnect, null);
Console.WriteLine("服务器开启成功");
}
//回调方法 就是循环调用(创建度无趣和客户端的连接)
void NewConnect(IAsyncResult link)
{
try
{
//相当服务器和客户端的连接通道
Socket socket = listen.EndAccept(link);
if (NewIndex() < 0)
{
socket.Close();
Console.WriteLine("为连接失败或人数已满");
}
else
{
//把链接里成功的用户赋值给当前变量
Client_side client = clients[NewIndex()];
//初始化套接字
client.Init(socket);
//获取当前客户端的ip
string cliIp = client.GetportNumber();
Console.WriteLine("ID为:" + NewIndex() + "连接的IP:" + cliIp);
//解析数据包内的内容
client.socket.BeginReceive(client.byteArray, client.clientCount, client.residueCount(), SocketFlags.None, AnalysisByte, null);
//伪递归 自己调用自己
listen.BeginAccept(NewConnect, null);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
///解析从客户端接收到的数据包
/// </summary>
/// <param name="link"></param>
void AnalysisByte(IAsyncResult link)
{
Client_side client = (Client_side)link.AsyncState;//当前客户端的状态
try
{
int index = client.socket.EndReceive(link);//获取当前数据包读取的进度
if (index <= 0)
{
Console.WriteLine("IP为:" + client.GetportNumber() + "断开连接");
client.Colse();
}
string str = Encoding.Default.GetString(client.byteArray, 0, index);
str = client.GetName() + ":" + str;
byte[] by = Encoding.Default.GetBytes(str);
//广播
for (int i = 0; i < clients.Length; i++)
{
//当前连接为空或者是没有连接成功
if (clients[i] == null || !clients[i].isside)
{
continue;
}
//发送消息
clients[i].socket.Send(by);
}
//伪递归 循环调用 //重新调用一次 把没读完的数据包读取完整
client.socket.BeginReceive(client.byteArray, client.clientCount, client.residueCount(), SocketFlags.None, AnalysisByte, client);
}
catch (Exception e)
{
Console.WriteLine("解析错误,报错的代码为:" + e.Message);
client.Colse();
}
}
}
}