Socket实现客户端和服务器简单通信案例
一、服务端
1、主界面
2、远端连接Socket客户端集合
//将远程连接的客户端的IP地址和Socket存入集合中
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
3、监听事件
/// <summary>
/// 监听按钮事件
/// </summary>
private void btListener_Click(object sender, EventArgs e)
{
//在服务器端创建一个负责监听IP地址和端口的Socket
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Any; // IPAddress.Parse(tbIP.Text);
//创建端口对象
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(tbPort.Text));
//监听
socketWatch.Bind(point);
ShowMsg("监听成功");
//设置监听最大客户端数量
socketWatch.Listen(10);
//创建监听线程
Thread th = new Thread(Listen);
th.IsBackground = true;
th.Start(socketWatch);
}
/// <summary>
/// 等待客户端的连接,并创建一个负责通信的Socket
/// </summary>
/// <param name="socketWatch"></param>
void Listen( object o)
{
//object 转为 Socket
Socket socketWatch = o as Socket;
//等待客户端的连接,并创建一个负责通信的Socket
while (true)
{
try
{
Socket socketSend = socketWatch.Accept();
//将远程的连接的客户端的IP地址和Socket存入集合中
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将远程的连接的客户端的IP地址和Socket加入到下拉框
cbClients.Items.Add(socketSend.RemoteEndPoint.ToString());
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功!");
Thread th = new Thread(Receive);
th.IsBackground = true;
th.Start(socketSend);
}
catch (Exception)
{
}
}
}
/// <summary>
/// 界面输出文字方法
/// </summary>
public void ShowMsg(string str)
{
tbReceiveContent.AppendText(str + "\r\n");
}
4、处理接收信息
/// <summary>
/// 处理接收信息方法
/// </summary>
/// <param name="o"></param>
void Receive(object o)
{
Socket socketSend = o as Socket;
while (true)
{
try
{
//客户端连接成功后,服务器应嘎爱接收客户发来的消息
byte[] buffer = new byte[104 * 1024 * 3];
//返回实际接收的有效字节长度
int r = socketSend.Receive(buffer);
if (r == 0)
{
break;
}
#region 根据不同的功能码做出处理
//1.接收发送的文字
if (buffer[0]==0)
{
//字节转为字符串
string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
//2.接收发送的文件
else if (buffer[0] == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = @"C:\Users\mingliang\Desktop\TEST\Receive";//设置初始目录
sfd.Title = "请选择保存文件的目录";
sfd.Filter = "所有文件|*.*";
sfd.ShowDialog(this);//加this
//保存文件
string savepath = sfd.FileName;
using (FileStream fswrite = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.Write))
{
fswrite.Write(buffer, 1, r - 1);
}
MessageBox.Show("保存成功~");
}
//3.接收发送的抖动窗口
else if (buffer[0] == 2)
{
ZD();
}
#endregion
}
catch (Exception)
{
}
}
}
//模拟抖动
void ZD()
{
for (int i = 0; i < 100; i++)
{
this.Location = new Point(200,200);
this.Location = new Point(250, 250);
}
}
5、发送文字信息
/// <summary>
/// 根据选择的客户端,进行发送文本
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSendMsg_Click(object sender, EventArgs e)
{
try
{
string str = tbSendContent.Text.Trim();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
List<byte> list = new List<byte>();
list.Add(0);
list.AddRange(buffer);
//将泛型集合转换为数组
byte[] newbuffer = list.ToArray();
//向选中的客户端发送文本
string ip = cbClients.SelectedItem.ToString();
dicSocket[ip].Send(newbuffer);
}
catch (Exception)
{
}
}
6、发送文件
/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSendFile_Click(object sender, EventArgs e)
{
//获取发送文件的路径
string filepath = tbFilePath.Text;
using (FileStream fsRead=new FileStream(filepath,FileMode.Open,FileAccess.Read))
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = fsRead.Read(buffer, 0, buffer.Length);
//File.ReadAllText(".\\TNS.txt").Trim();
List<byte> list = new List<byte>();
list.Add(1);//功能码:1
list.AddRange(buffer);
byte[] newbuffer = list.ToArray();
//向选中的客户端发送文件
dicSocket[cbClients.SelectedItem.ToString()].Send(newbuffer, 0, r + 1, SocketFlags.None);//加上功能码,长度加1
}
}
/// <summary>
/// 选择发送的文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSelecctFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"C:\Users\mingliang\Desktop\TEST\Send";
ofd.Title = "请选择要发送的文件";
ofd.Filter = "所有文件|*.*";
ofd.ShowDialog();
tbFilePath.Text = ofd.FileName;
}
7、模拟发送抖动窗口
/// <summary>
/// 发送震动窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btZD_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[1];
//功能码
buffer[0] = 2;
//向选中的客户端发送模拟抖动窗口
dicSocket[cbClients.SelectedItem.ToString()].Send(buffer);
}
二、客户端
1、主界面
2、连接事件
Socket socketSend;
/// <summary>
/// 连接按钮事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btConnect_Click(object sender, EventArgs e)
{
//创建负责通信的Socket
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress serverip = IPAddress.Parse(tbServerIP.Text);
//创建端口对象
IPEndPoint point = new IPEndPoint(serverip, Convert.ToInt32(tbPort.Text));
//获取要连接的远程服务器应用程序的ip地址和端口号
socketSend.Connect(point);
ShowMsg("连接成功!");
//开启一个新的线程,不停的接收服务器发来的消息
Thread th = new Thread(Receive);
th.IsBackground = true;
th.Start();
}
/// <summary>
/// 界面输出文字方法
/// </summary>
/// <param name="str"></param>
public void ShowMsg(string str)
{
tbReceiveContent.AppendText(str + "\r\n");
}
3、处理接收信息
/// <summary>
/// 不停的接收服务器发来的消息
/// </summary>
void Receive()
{
while (true)
{
byte[] buffer = new byte[1024 * 1024 * 3];
//接收数组的实际长度
int r = socketSend.Receive(buffer);
if (r==0)
{
break;
}
//1.发送消息
if (buffer[0] == 0)
{
//字节转为字符串
string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
//2.发送文件
else if (buffer[0] == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = @"C:\Users\mingliang\Desktop\TEST\Receive";
sfd.Title = "请选择保存文件的目录";
sfd.Filter = "所有文件|*.*";
sfd.ShowDialog(this);
//保存文件
string savepath = sfd.FileName;
using (FileStream fswrite =new FileStream (savepath,FileMode.OpenOrCreate,FileAccess.Write))
{
fswrite.Write(buffer, 1, r - 1);
}
MessageBox.Show("保存成功~");
}
//3.抖动窗口
else if (buffer[0] == 2)
{
ZD();
}
}
}
/// <summary>
/// 模拟震动
/// </summary>
void ZD()
{
for (int i = 0; i < 100; i++)
{
this.Location = new Point(250, 250);
this.Location = new Point(200, 200);
}
}
4、发送文字信息
/// <summary>
/// 客户端向服务器发送文字消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSendMsg_Click(object sender, EventArgs e)
{
string str = tbSendContent.Text.Trim();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
//socketSend.Send(buffer);
List<byte> list = new List<byte>();
list.Add(0);
list.AddRange(buffer);
//将泛型集合转换为数组
byte[] newbuffer = list.ToArray();
socketSend.Send(newbuffer);
}
5、发送文件
/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSendFile_Click(object sender, EventArgs e)
{
//获取发送文件的路径
string filepath = tbFilePath.Text;
using (FileStream fsRead = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = fsRead.Read(buffer, 0, buffer.Length);
List<byte> list = new List<byte>();
list.Add(1);
list.AddRange(buffer);
byte[] newbuffer = list.ToArray();
socketSend.Send(newbuffer, 0, r + 1, SocketFlags.None);
}
}
/// <summary>
/// 选择发送的文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSelecctFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"C:\Users\mingliang\Desktop\TEST\Send";
ofd.Title = "请选择要发送的文件";
ofd.Filter = "所有文件|*.*";
ofd.ShowDialog();
tbFilePath.Text = ofd.FileName;
}
6、模拟发送抖动窗口
/// <summary>
/// 模拟发送抖动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btZD_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[1];
buffer[0] = 2;
socketSend.Send(buffer);
}
本文来自博客园,作者:码农阿亮,转载请注明原文链接:https://www.cnblogs.com/wml-it/p/16082331.html
技术的发展日新月异,随着时间推移,无法保证本博客所有内容的正确性。如有误导,请大家见谅,欢迎评论区指正!
开源库地址,欢迎点亮:
GitHub:https://github.com/ITMingliang
Gitee: https://gitee.com/mingliang_it
GitLab: https://gitlab.com/ITMingliang
建群声明: 本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,为大家答疑解惑。热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得!进群方式:扫码关注公众号,后台回复【进群】。