z
1 客户端
//客户端 通信套接字
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
Socket sokMsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.获取要连接的服务端 节点
//2.1获取网络节点对象
IPAddress address = IPAddress.Parse(txtIP.Text);//127.0.0.1
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text));//10001
//3.向服务端 发送链接请求
sokMsg.Connect(endPoint);
//4.开启通信线程
//客户端 通信线程
Thread thrMsg = new Thread(RecevieMsg);
thrMsg.IsBackground = true;
thrMsg.SetApartmentState(ApartmentState.STA);//在winform7 要用到
thrMsg.Start();
------------------------------
void RecevieMsg()
{
//3.1创建 消息缓存区
byte[] arrMsg = new byte[1024 * 1024 * 1];
try
{
while (isRec)
{
//此处 接收 服务器发来的数据中,因为包含了一个 标识符,所以内容的真实长度,应该 - 1
int realLength = sokMsg.Receive(arrMsg) - 1;// Receive 会阻断线程
switch (arrMsg[0])
{
case 0://接收到文本消息
GetMsg(arrMsg, realLength);
break;
case 1://
GeFile(arrMsg, realLength);
break;
default:
break;
}
}
}
catch (Exception ex)
{
sokMsg.Close();
sokMsg = null;
ShowMsg("服务端断开连接!");
}
}
2 在服务端
private void btnStartListen_Click(object sender, EventArgs e)
{
try
{
//1.创建【监听套接字】 使用 ip4协议,流式传输,TCP连接
sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.绑定端口
//2.1获取网络节点对象
IPAddress address = IPAddress.Parse(txtIP.Text);//127.0.0.1
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text));//10001
//2.2绑定端口(其实内部 就向系统的 端口表中 注册 了一个端口,并指定了当前程序句柄)
sokWatch.Bind(endPoint);
//2.3设置监听队列(指,限制 同时 处理的 连接请求数--即同时处理的客户端连接请求)
sokWatch.Listen(10);
//2.4开始监听,调用监听线程 执行 监听套接字的 监听方法
thrWatch = new Thread(WatchConnecting);
thrWatch.IsBackground = true;
thrWatch.Start();
ShowMsg("服务器启动啦~~!");
}
catch (SocketException sex)
{
MessageBox.Show("异常:" + sex);
}
catch (Exception ex)
{
MessageBox.Show("异常:" + ex);
}
}
/// <summary>
/// 服务端监听方法
/// </summary>
void WatchConnecting()
{
try
{
//循环监听 客户端的 连接请求
while (isWatch)
{
//2.4开始监听:此方法会阻断当前线程,直到有 其它程序 连接过来,才执行完毕
Socket sokMsg = sokWatch.Accept();
//2.5创建通信管理类
MsgConnection conn = new MsgConnection(sokMsg, ShowMsg, RemoveClient);
//将当前连接成功的 【与客户端通信的套接字】 的 标识 保存起来,并显示到 列表中
//将 远程客户端的 ip和端口 字符串 存入 列表
lbOnline.Items.Add(sokMsg.RemoteEndPoint.ToString());
//将 服务端的通信套接字 存入 字典集合
dictCon.Add(sokMsg.RemoteEndPoint.ToString(), conn);
ShowMsg("有客户端连接了~~!");
}
}
catch (Exception ex)
{
ShowMsg("异常:" + ex);
}
}
// 发送消息
sokMsg.Send();
/// <summary>
/// 断开socket连接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btdisConnect_Click(object sender, EventArgs e)
{
//如果当前客户端的链接socket不为空并且处于和服务器的链接状态时,断开当前链接
if (cSocket != null && cSocket.Connected)
{
cSocket.Disconnect(false);
}
}
----------------------------可以将一个实体序列化成数组
/// <summary>
/// 将对象序列化成byte[]数组的帮助类,提供序列化和反序列功能
/// </summary>
public class SerDesrHelper
{
/// <summary>
/// 将对象序列化成byte数组
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static byte[] Serialization(object obj)
{
byte[] buffer;
//1 初始化一个二进制流的序列化器
BinaryFormatter ser = new BinaryFormatter();
// 2 定义一个内存流,用来接收二进制流的序列化器将对象obj序列化以后的byte[]数组
using (MemoryStream ms = new MemoryStream())
{
// 3 调用二进制流的序列化器Serialize()方法将obj序列化成二进制流保存到ms中
ser.Serialize(ms, obj);
//4 要将ms的当前流指针定位到0的位置
ms.Position = 0;
// 5 定义一个ms长度的接收byte[]数组
buffer = new byte[ms.Length];
// 6 将ms中的内容读到byte[]数组buffer中
ms.Read(buffer, 0, buffer.Length);
}
// 7 返回有内容的buffer
return buffer;
}
/// <summary>
/// 将byte数组字节码反序列化成相应的对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="objbty"></param>
/// <returns></returns>
public static T Deserialize<T>(byte[] objbty)
{
if (objbty.Length == 0) return default(T);
//1 初始化一个二进制流的序列化器
BinaryFormatter ser = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(objbty))
{
return (T)ser.Deserialize(ms);
}
}
}