用TCP协议处理分包、粘包是比较麻烦的,所以写了Helper类,完整代码如下:
public class TcpHelper
{
#region TCP模块
byte[] result = new byte[1024 * 1024]; //接收1M的数据
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//static string ipAddress = ConfigurationInfo_Client.Api;
//int port = Convert.ToInt32(ConfigurationInfo_Client.Port);
static string ipAddress = "192.168.123.31";
int port = Convert.ToInt32("19219");
IPAddress ip = IPAddress.Parse(ipAddress);
string message2 = "1001{\"code\":\"" + "123456" + "\"}";
/// <summary>
/// 初始化TCP协议方法(首先登录)
/// </summary>
public void tcp()
{
try
{
if (clientSocket.Connected)
{
//clientSocket.Send(getSendByte(message2));
//string rec = tcpReceive(); //发送了登录信息后,要接收一下数据
}
else
{
clientSocket.Connect(new IPEndPoint(ip, port));
clientSocket.Send(getSendByte(message2));
string rec = tcpReceive(); //发送了登录信息后,要接收一下数据
}
}
catch (Exception e)
{
//MessageBox.Show(e.ToString());
}
}
/// <summary>
/// 使用TCP发送消息
/// </summary>
/// <param name="mess"></param>
public void tcpSendMessage(string mess)
{
try
{
if (clientSocket.Connected)
{
clientSocket.Send(getSendByte(mess));
}
else
{
//没有登录那就先登录
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(new IPEndPoint(ip, 9527));
if (clientSocket.Connected)
{
clientSocket.Send(getSendByte(message2));
string str = tcpReceive(); //发送了登录信息后,要接收一下数据
clientSocket.Send(getSendByte(mess));
}
}
}
catch (Exception e)
{
}
}
/// <summary>
/// 计算发送端的字节长度
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public byte[] getSendByte(string str)
{
byte[] a = Encoding.UTF8.GetBytes(str);
int aa = a.Length;
byte b3 = (byte)((aa >> 24) & 0xff);
byte b2 = (byte)((aa >> 16) & 0xff);
byte b1 = (byte)((aa >> 8) & 0xff);
byte b0 = (byte)(aa & 0xff);
byte[] req = new byte[aa + 4];
req[0] = b0;
req[1] = b1;
req[2] = b2;
req[3] = b3;
System.Array.Copy(a, 0, req, 4, aa);
return req;
}
/// <summary>
/// 计算接收的字节长度
/// </summary>
/// <param name="by"></param>
/// <returns></returns>
public int getLen(byte[] by)
{
int length = 0;
length += ((by[0]) & 0xff);
length += ((by[1] & 0xff) << 8);
length += ((by[2] & 0xff) << 16);
length += ((by[3] & 0xff) << 24);
return length;
}
/// <summary>
/// 接收消息
/// </summary>
/// <returns></returns>
public string tcpReceive()
{
try
{
if (clientSocket.Connected)
{
clientSocket.ReceiveTimeout = 3000; //三秒超时
//这里进行循环读取
int num = clientSocket.Receive(result);
int strLen = getLen(result);
string str = Encoding.UTF8.GetString(result, 4, strLen); //这里报错
if (!string.IsNullOrWhiteSpace(str))
{
return str;
}
}
else
{
tcp();
}
return "";
}
catch (Exception e)
{
return "出现异常";
}
}
#endregion
}
登录是我的项目特有的逻辑,不需要的朋友可以删掉或者不用,其他的发送和接收消息是根据小端模式来进行,亲测好用。