实际项目中会用到客户端请求服务端,然后服务端给客户端反馈相应的消息。其中Socket就是一种很好的方式。
服务端代码:以控制台应用的方式来体现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入socket命名空间
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
class Program
{
static void Main(string[] args)
{
//创建socket对象,使用常用的tcp协议,使用ipv4协议
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//给该socket服务设置固定端口 例如:4476
socket.Bind(new IPEndPoint(IPAddress.Any, 4476));
//启动监听,设置最大连接数例如 4个客户端访问
socket.Listen(4);
//开始接受客户端请求
socket.BeginAccept(new AsyncCallback((ls) => {
//客户端socket实例
var client = socket.EndAccept(ls);
//给客户端发送一个消息
client.Send(Encoding.Unicode.GetBytes(string.Format("欢迎连接SocketServer,时间:{0}", System.DateTime.Now)));
}), null);
Console.WriteLine("Socket Server is ready");
Console.Read();
}
}
}
运行出来结果:
客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入命名空间
using System.Net.Sockets;
namespace SocketClient
{
class Program
{
static void Main(string[] args)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//设置socket连接 端口为socketServer的端口
socket.Connect("localhost", 4476);
//实现客户端接收服务端消息的方法
var bit = new byte[1024];//设置缓冲区,用来保存数据
socket.BeginReceive(bit, 0, bit.Length, SocketFlags.None, new AsyncCallback((ls) => {
var length = socket.EndReceive(ls);
//读出消息内容
var ms = Encoding.Unicode.GetString(bit,0,length);
//打印消息内容
Console.WriteLine(ms);
}), null);
Console.WriteLine("client is connect server");
Console.Read();
}
}
}
先运行服务端,再运行客户端,结果如下图:
该方式只能实现服务端给客户端发送一次消息。接下来对它进行改造。
实现服务端定期给客户端发消息:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入socket命名空间
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
class Program
{
static void Main(string[] args)
{
//创建socket对象,使用常用的tcp协议,使用ipv4协议
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//给该socket服务设置固定端口 例如:4476
socket.Bind(new IPEndPoint(IPAddress.Any, 4476));
//启动监听,设置最大连接数例如 4个客户端访问
socket.Listen(4);
//开始接受客户端请求
socket.BeginAccept(new AsyncCallback((ls) => {
//客户端socket实例
var client = socket.EndAccept(ls);
//给客户端发送一个消息
client.Send(Encoding.Unicode.GetBytes(string.Format("欢迎连接SocketServer,时间:{0}", System.DateTime.Now)));
//设置定时器,服务器每间隔2秒给客户端发送一段消息
var timer = new System.Timers.Timer();
timer.Interval = 2000;
timer.Enabled = true;
timer.Elapsed += (a, c) => {
client.Send(Encoding.Unicode.GetBytes(string.Format("消息定期发送,时间:{0}", System.DateTime.Now)));
};
timer.Start();
}), null);
Console.WriteLine("Socket Server is ready");
Console.Read();
}
}
}
同样客户端也得做相应改造
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入命名空间
using System.Net.Sockets;
namespace SocketClient
{
class Program
{
static void Main(string[] args)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//设置socket连接 端口为socketServer的端口
socket.Connect("localhost", 4476);
//实现客户端接收服务端消息的方法
socket.BeginReceive(bit, 0, bit.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
Console.Read();
}
static byte[] bit = new byte[1024];
public static void ReceiveMessage(IAsyncResult ar)
{
try
{
var socket = ar.AsyncState as Socket;
var length = socket.EndReceive(ar);
//读取出来消息内容
var message = Encoding.Unicode.GetString(bit, 0, length);
//显示消息
Console.WriteLine(message);
//接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
socket.BeginReceive(bit, 0, bit.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
运行后的结果如下图:
当关闭服务端时,客户端会出错
当关闭客户端时会出现错误:
这就得判断客户端是否存在,若不存在则不能继续发送消息。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//引入socket命名空间
using System.Net;
using System.Net.Sockets;
namespace SocketServer
{
class Program
{
static void Main(string[] args)
{
//创建socket对象,使用常用的tcp协议,使用ipv4协议
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//给该socket服务设置固定端口 例如:4476
socket.Bind(new IPEndPoint(IPAddress.Any, 4476));
//启动监听,设置最大连接数例如 4个客户端访问
socket.Listen(4);
//开始接受客户端请求
socket.BeginAccept(new AsyncCallback((ls) => {
//客户端socket实例
var client = socket.EndAccept(ls);
//给客户端发送一个消息
client.Send(Encoding.Unicode.GetBytes(string.Format("欢迎连接SocketServer,时间:{0}", System.DateTime.Now)));
//设置定时器,服务器每间隔2秒给客户端发送一段消息
var timer = new System.Timers.Timer();
timer.Interval = 2000;
timer.Enabled = true;
timer.Elapsed += (o, b) => {
//监测客户端的状态
if(client.Connected)
{
try
{
client.Send(Encoding.Unicode.GetBytes(string.Format("消息定期发送,时间:{0}", System.DateTime.Now)));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
else
{
timer.Stop();
timer.Enabled = false;
Console.WriteLine("客户端已断开连接,消息发送停止!");
}
};
timer.Start();
}), null);
Console.WriteLine("Socket Server is ready");
Console.Read();
}
}
}
目前我们实现的场景很简单,服务器只管发消息,客户端只管收消息