Socket编程基于TCP服务器框架
(一)Socket编程客户端连接服务器实现简单通信
首先要了解Socket基础性的概念和知识点,这里不过多讲解。
Socket服务器和客户端通信的原理:
根据上图的原理直接上代码:
1、创建服务端
(1)首先要引用Mysql.Data.dll应用程序;
(2)单独创建一个类Severs,使用线程来接受和发送消息;
(3)Program类作为测试类
添加命名空间
// An highlighted block
using System.Net.Sockets;
using System.Net;
using System.Threading;
写一个方法StartServer来开启服务器
// An highlighted block
public static void StartServer()
{
serverS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//使用try{}catch{}来捕获异常
try
{
IPAddress ips = IPAddress.Parse("127.0.0.1");
IPEndPoint ipp = new IPEndPoint(ips, 8888);
serverS.Bind(ipp);
serverS.Listen(0);//0表示无限监听
Console.WriteLine("服务器启动成功");
Thread acceptThread = new Thread(AcceptClient);//开启一个线程
acceptThread.Start();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
接受客户端连接,方法名对应上面线程里的方法名
// An highlighted block
static void AcceptClient()
{
while (true)
{
Socket client = serverS.Accept();
clientlist.Add(client);//用一个集合List<>来存储已连接的客户端
client.Send(Encoding.Default.GetBytes("你已成功连接服务器"));//连接成功后向客户端发送连接成功信息
Thread rec = new Thread(receiveMessage);//新开启一个线程来接受信息
rec.IsBackground = true;//随着主线程关闭而关闭
rec.Start(client);//开启线程
}
}
接受信息receiveMessage方法
// An highlighted block
static void receiveMessage(object client)
{
Socket cli = client as Socket;
try
{
byte[] buffs = new byte[1024];//数组存储接收到的消息
while (true)
{
int sumBts = cli.Receive(buffs);//接收消息
string yy = Encoding.UTF8.GetString(buffs, 0, sumBts);//把数组格式转换为字符串,(“数组内容”, “开始转换的位置”, “转换长度”)
Console.WriteLine(cli.RemoteEndPoint+":"+yy);
SendMessage(Encoding.Default.GetBytes(cli.RemoteEndPoint+":"+yy));//把接受到的内容广播给其他人
}
}
catch (Exception e)
{
Console.WriteLine("消息接收失败");
clientlist.Remove(cli);//移除客户端
cli.Shutdown(SocketShutdown.Both);//关闭发送和接受功能
}
}
发送信息SendMessage方法
// An highlighted block
public static void SendMessage(string ss)
{
byte[] bb = Encoding.UTF8.GetBytes(ss);
foreach(Socket me in clientlist)//循环遍历集合里面连接的客户端
{
me.Send(bb);
}
}
完整Severs类代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Sever
{
class Severs
{
private static Socket serverS;
static List<Socket> clientlist = new List<Socket>();
public static void StartServer()
{
serverS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IPAddress ips = IPAddress.Parse("127.0.0.1");
IPEndPoint ipp = new IPEndPoint(ips, 8888);
serverS.Bind(ipp);
serverS.Listen(0);
Console.WriteLine("server success");
Thread acceptThread = new Thread(AcceptClient);
acceptThread.Start();
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
// serverS.Close();
}
}
static void AcceptClient()
{
while (true)
{
Socket client = serverS.Accept();
clientlist.Add(client);
client.Send(Encoding.Default.GetBytes("你已成功连接服务器"));
Thread rec= new Thread(receiveMessage);
rec.IsBackground = true;
rec.Start(client);
}
}
static void receiveMessage(object client)
{
Socket cli = client as Socket;
try
{
byte[] buffs = new byte[1024];
while (true)
{
int sumBts = cli.Receive(buffs);
string yy = Encoding.UTF8.GetString(buffs, 0, sumBts);
Console.WriteLine(cli.RemoteEndPoint+":"+ yy);
SendMessage(Encoding.Default.GetBytes(cli.RemoteEndPoint + ":"+yy));
}
}
catch (Exception e)
{
Console.WriteLine("消息接收失败");
clientlist.Remove(cli);
cli.Shutdown(SocketShutdown.Both);
}
}
public static void SendMessage(string ss)
{
byte[] bb = Encoding.UTF8.GetBytes(ss);
foreach(Socket me in clientlist)
{
me.Send(bb);
}
}
}
}
完整Program测试类代码
using System;
using System.Text;
namespace Sever
{
class Program
{
static void Main(string[] args)
{
Severs.StartServer();//使用静态方法,直接类+方法名
}
}
}
2、客户端
这里为了方便使用控制台来编辑;后面会使用Unity来写
(1)同样首先要引用Mysql.Data.dll应用程序;
(2)同样单独创建一个类Clients,使用线程来接受和发送消息;
(3)Program类作为测试类
添加命名空间
// An highlighted block
using System.Net.Sockets;
using System.Net;
using System.Threading;
创建连接服务器Connect方法
// An highlighted block
public static void Connect()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ips = new IPEndPoint(ip, 8888);
socket.Connect(ips);//连接服务器
Console.WriteLine("连接服务器成功");
Thread th = new Thread(Remessage);//开启一个接受信息的线程
th.Start();
}
接受信息Remessage方法
// An highlighted block
private static void Remessage()
{
byte[] ss = new byte[1024 * 1024];
while(true)
{
int len = socket.Receive(ss);
string content = Encoding.UTF8.GetString(ss, 0, len);
Console.WriteLine(content);
}
}
发送信息SendMessages方法
// An highlighted block
public static void SendMessages(string me)
{
socket.Send(Encoding.Default.GetBytes(me));
}
测试类Program
// An highlighted block
static void Main(string[] args)
{
Clients.Connect();
Console.WriteLine("请输入内容...");
string ss = Console.ReadLine();
while(ss != null)
{
Clients.SendMessages(ss);
ss = Console.ReadLine();
}
Console.ReadLine();
}
完整Clients类代码
// An highlighted block
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System;
using System.Text;
namespace Client
{
class Clients
{
static Socket socket;
public static void Connect()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint ips = new IPEndPoint(ip, 8888);
socket.Connect(ips);
Console.WriteLine("连接服务器成功");
Thread th = new Thread(Remessage);
th.Start();
}
private static void Remessage()
{
byte[] ss = new byte[1024 * 1024];
while (true)
{
int len = socket.Receive(ss);
string content = Encoding.UTF8.GetString(ss, 0, len);
Console.WriteLine(content);
}
}
public static void SendMessages(string me)
{
socket.Send(Encoding.UTF8.GetBytes(me));
}
}
}
完整Program类代码
// An highlighted block
using System;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Clients.Connect();
Console.WriteLine("请输入内容...");
string ss = Console.ReadLine();
while(ss != null)
{
Clients.SendMessages(ss);
ss = Console.ReadLine();
}
Console.ReadLine();
}
}
}
运行结果:
- 谢谢大家,有什么疑问和错误可以提出来哟!后面会讲解游戏服务器框架构造。