1.消息结构
定义客户端和服务器之间的消息结构,便于消息的发送和接收。
消息Message包括序号ID和消息体Body,函数GetMessageByte和GetMessage相当于消息的压缩与解压。
public class Message
{
public Int16 ID { get; set; }
public byte[] Body { get; set; }
public static byte[] GetMessageByte(Message msg)
{
using (var stream = new MemoryStream())
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(msg.ID);
writer.Write(msg.Body.Length);
writer.Write(msg.Body);
return stream.ToArray();
}
}
}
public static Message GetMessage(byte[] data)
{
if (data == null)
{
return null;
}
Message msg = new Message();
using (var ms = new MemoryStream(data))
{
using (var br = new BinaryReader(ms))
{
msg.ID = br.ReadInt16();
msg.Body = br.ReadBytes(br.ReadInt32());
}
}
return msg;
}
}
2.服务器端
服务器端启动线程,接受客户端的连接。工作线程解析客户端的数据,并发送数据回应客户端。
public class MessageServer
{
private bool _isListening = false;
private int _port;
private Socket _server;
private Thread _thListen;
public MessageServer(int port)
{
_port = port;
}
public void Start()
{
if(_isListening)
return ;
try
{
IPAddress address = IPAddress.Any;
EndPoint point = new IPEndPoint(address, _port);
//创建Socket
_server = new Socket(address.AddressFamily,SocketType.Stream, ProtocolType.Tcp);
//绑定IP和端口号
_server.Bind(point);
//开始监听,等待客户连接
_server.Listen(1024);
_thListen = new Thread(ListenLoop);
_thListen.Start();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void Stop()
{
if (!_isListening)
return;
try
{
_server.Close();
if (_thListen.IsAlive)
{
_thListen.Join();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
_isListening = false;
}
}
private void ListenLoop()
{
_isListening = true;
try
{
while (true)
{
//获取客户的Socket
Socket client = _server.Accept();
Thread thClient = new Thread(new ParameterizedThreadStart(HandleClient));
thClient.Start(client);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void HandleClient(object obj)
{
Socket client = obj as Socket;
try
{
if (client == null)
{
throw new Exception("param error,not socket");
}
while (true)
{
//接收客户端的消息
byte[] msg = ReadMessage(client);
if (msg == null || msg.Length == 0)
{
Console.WriteLine("read message failed");
break;
}
Message message = Message.GetMessage(msg);
Message response = new Message
{
ID = (short)(message.ID +1),
Body = message.Body
};
//向客户端发送数据
WriteMessages(client, Message.GetMessageByte(response));
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
try
{
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
private readonly int headSize = 6;
private byte[] ReadMessage(Socket socket)
{
try
{
byte[] head = new byte[headSize];
int cur = 0;
do
{
cur += socket.Receive(head, cur, headSize - cur, SocketFlags.None);
} while (cur < headSize);
Int32 bodySize = 0;
using (var br = new BinaryReader(new MemoryStream(head)))
{
br.ReadInt16();
bodySize = br.ReadInt32();
}
if (bodySize > 0)
{
byte[] msg = new byte[headSize + bodySize];
Array.Copy(head, msg, headSize);
cur = headSize;
bodySize += headSize;
do
{
cur += socket.Receive(msg, cur, bodySize - cur, SocketFlags.None);
} while (cur < bodySize);
return msg;
}
else
{
return head;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return null;
}
}
private void WriteMessages(Socket socket, byte[] data)
{
if (data == null || data.Length == 0)
return;
try
{
int index = 0;
do
{
index += socket.Send(data, index, data.Length - index, SocketFlags.None);
} while (index < data.Length);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
class Program
{
static void Main(string[] args)
{
MessageServer svr = new MessageServer (1025);
svr.Start();
Console.ReadLine();
if (svr != null)
{
svr.Stop();
}
}
}
3.客户端
客户端向服务器端发送一条数据,并接收服务器的回复。
class Program
{
static void Main(string[] args)
{
//1.创建客户端socket
Socket client = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.发起建立连接的请求
IPAddress address = IPAddress.Parse("192.168.0.4");
EndPoint point = new IPEndPoint(address, 1025);
client.Connect(point);
//4.向服务器发送消息
byte[] body = System.Text.Encoding.Default.GetBytes("Give me data!");
Message message = new Message
{
ID = 2,
Body = body
};
byte[] msg = Message.GetMessageByte(message);
WriteMessages(client,msg);
//3.接收服务器的消息
byte[] response = ReadMessage(client);
Message result = Message.GetMessage(response);
}
}