一、服务端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace Server
{
class Program
{
static void Main(string[] args)
{
startServer();
Console.ReadKey();
}
static void startServer()
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 88);
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(0);
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
static messageInfo msgInfo = new messageInfo();
static void AcceptCallBack(IAsyncResult ar)
{
Socket serverSocket = ar.AsyncState as Socket;
Socket clientSocket = serverSocket.EndAccept(ar);
clientSocket.Send(Encoding.UTF8.GetBytes("欢迎连接,你好客户端"));
clientSocket.BeginReceive(msgInfo.Data, msgInfo.StartIndex, msgInfo.RemainSize, SocketFlags.None, receiveCallBack, clientSocket);
serverSocket.BeginAccept(AcceptCallBack, serverSocket);
}
static byte[] receiveMsg = new byte[1024];
static void receiveCallBack(IAsyncResult ar)
{
Socket clientSocket = null;
try
{
clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
if (count == 0)
{
clientSocket.Close();
return;
}
msgInfo.AddCount(count);
msgInfo.ReadMessage();
clientSocket.BeginReceive(msgInfo.Data, msgInfo.StartIndex, msgInfo.RemainSize, SocketFlags.None, receiveCallBack, clientSocket);
}
catch (Exception e)
{
Console.WriteLine(e);
if (clientSocket != null)
{
clientSocket.Close();
return;
}
}
}
}
}
服务端处理粘包分包:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class messageInfo
{
//用于存储接受到的报文
private byte[] data = new byte[1024];
//接收的报文byte的数量
private int startIndex = 0;
#region 属性
//报文
public byte[] Data
{
get
{
return data;
}
}
//接收的报文byte的数量
public int StartIndex
{
get { return startIndex; }
}
//data数组里还剩余的大小
public int RemainSize
{
get { return data.Length - startIndex; }
}
#endregion
//对报文byte数量的处理
public void AddCount(int count)
{
startIndex += count;
}
public void ReadMessage()
{
while (true)
{
//如果接收到的数据的个数少于等于4,即少于报头的大小
if (startIndex <= 4) return;
//如果大于报头的长度,把报头转换成数字。ToInt32在处理byte时,从0开始,只处理前四位
int count = BitConverter.ToInt32(data, 0);
//如果接收到的数据的个数,减去报头的大小,大于等于报文的长度,则处理报文。否则不处理
if ((startIndex - 4) >= count)
{
//从报头结尾处开始处理,处理count个,count即报文的个数
string s = Encoding.UTF8.GetString(data, 4, count);
Console.WriteLine("解析出一条数据 : == :" + s);
//处理报文后,则把剩余的数据向前移动。从count + 4的地方开始向前移动,移动到0处,移动的长度为接收到的数据减去报文的数量和报头的数量(即count + 4)
Array.Copy(data, count + 4, data, 0, startIndex - count - 4);
//移动完成后,处理startIndex即剩余的接收的数据个数
startIndex -= (count + 4);
}
else
{
break;
}
}
}
}
}
二、客户端处理代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress,88);
clientSocket.Connect(ipEndPoint);
byte[] receiveMsg = new byte[1024];
int count = clientSocket.Receive(receiveMsg);
Console.WriteLine(Encoding.UTF8.GetString(receiveMsg,0,count));
while (true)
{
string sendMsg = Console.ReadLine();
clientSocket.Send(messageInfo.GetBytes(sendMsg));
}
Console.ReadKey();
}
}
}
客户端处理粘包分包代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class messageInfo
{
/// <summary>
/// 把报头和报文封装到一块
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] GetBytes(string data)
{
//获取byte数据
byte[] dateInfo = Encoding.UTF8.GetBytes(data);
//获取报文长度
int length = dateInfo.Length;
//把报文长度转换成byte数组,作为报头存在
byte[] lengthByte = BitConverter.GetBytes(length);
//把报头和报文拼接起来,形成一个新的byte数组,返回
byte[] newData = lengthByte.Concat(dateInfo).ToArray();
return newData;
}
}
}