该小程序可以实现多个客户端连接服务器,服务器可以指定发送消息给哪个客户端。连接进来的客户端北储存在combobox控件种,当客户端断开连接时,消息框会显示断开的信息,控件会删除掉断开的客户端信息。服务器端可以发送消息、文件、振动。
服务器端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
namespace 服务器段
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
//创建服务器端的Socket
Socket tcpserivce = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
//将服务器端的Socket绑定Ip和端口号
IPAddress ip = IPAddress.Parse(txtServer.Text);//将ip转换为对应的格式
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//将IP和端口号组成point类
tcpserivce.Bind(point);//服务器绑定
ShowMsg("监听成功");
//允许连接总数
tcpserivce.Listen(10);
Thread th = new Thread(Listen);//开启线程监听客户端的连接情况
th.IsBackground = true;
th.Start(tcpserivce);
}
Socket socketSend;
/// <summary>
/// 监听客户端连接函数
/// </summary>
/// <param name="t"></param>
public void Listen(object t)
{
//获取服务器端的Socket
Socket tcpserivce = t as Socket;
while (true)//循环,保证一直可以接收客户端的连接
{
//接收到客户端的连接,创建新的socket与之通信
socketSend = tcpserivce.Accept();
//将远程连接的客户端的IP地址和Socket存入集合中
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将远程连接的客户端的IP地址和端口号存储下拉框中
cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
//显示连接成功
ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功");
//开启线程接收客户端的消息
Thread th1 = new Thread(Recive);
th1.IsBackground = true;
th1.Start(socketSend);
}
}
//将远程连接的客户端的IP地址和Socket存入集合中
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
//接收客户端的消息
public void Recive(object o)
{
//获取到客户端的socket
Socket socketSend = o as Socket;
while (true)
{
//判断该客户端是否断开连接
if (socketSend.Poll(10, SelectMode.SelectRead))
{
break;
}
byte[] buffer = new byte[1024 * 1024 * 2];
//实际接受到的有效字节数
int r = socketSend.Receive(buffer);
//将byte数组转换为string类型
string str = Encoding.UTF8.GetString(buffer, 0, r);
ShowMsg(socketSend.RemoteEndPoint + "说:" + str);
}
}
//消息框追加消息
void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
//发送消息给客户端
private void btnSend_Click(object sender, EventArgs e)
{
string str = txtMsg.Text;
//如果发送的是消息,在字节数组第一位加0以做标识
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
List<byte> list = new List<byte>();
list.Add(0);
list.AddRange(buffer);
//将泛型集合转换为数组
byte[] newBuffer = list.ToArray();
//获得用户在下拉框中选中的IP地址
if (cboUsers.SelectedItem == null)
{
txtLog.AppendText("没有选择发送的客户端" + "\r\n");
}
else
{
//获取要发送的客户端
string ip = cboUsers.SelectedItem.ToString();
dicSocket[ip].Send(newBuffer);
}
}
//选择要发送的文件
private void btnSelect_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
ofd.Title = "请选择要发送的文件";
ofd.Filter = "所有文件|*.*";
ofd.ShowDialog();
txtPath.Text = ofd.FileName;
}
//发送文件
private void btnSendFile_Click(object sender, EventArgs e)
{
//发送文件,在字节数组第一位添加1以做标识
string path = txtPath.Text;
using (FileStream freRead = new FileStream(path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024*1024*3];
int r = freRead.Read(buffer, 0, buffer.Length);
List<byte> list = new List<byte>();
list.Add(1);
list.AddRange(buffer);
byte[] newBuffer = list.ToArray();
dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);
}
}
//发送振动,在字节数组第一位添加2以做标识
private void btnZD_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[1];
buffer[0] = 2;
dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);
}
//每100毫秒检测客户端是否断开连接
private void timer1_Tick(object sender, EventArgs e)
{
//创建字典存放断开的客户端
Dictionary<string, Socket> delSocket = new Dictionary<string, Socket>();
//遍历检查哪些客户端断开了
foreach (var item in dicSocket)
{
if (item.Value.Poll(10, SelectMode.SelectRead))
{
delSocket.Add(item.Key,item.Value);
}
}
//删除掉断开的客户端
foreach (var item in delSocket)
{
dicSocket.Remove(item.Key);
cboUsers.Items.Remove(item.Key);
}
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 客户端
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Socket socketSend;
private void btnStart_Click(object sender, EventArgs e)
{
//创建客户端的socket,绑定服务器端ip和端口,准备连接
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtServer.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
try
{
socketSend.Connect(point);//连接服务器
ShowMsg("连接成功");
}
catch (Exception)
{
txtLog.AppendText("服务器未打开" + "\r\n");
}
//开启一个新的线程不停的接收服务端发来的消息
Thread th = new Thread(Recive);
th.IsBackground = true;
th.Start();
}
void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
}
//发送消息给服务器端
private void btnSend_Click(object sender, EventArgs e)
{
string str = txtMsg.Text.Trim();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
socketSend.Send(buffer);
}
//不停接收服务器消息
void Recive()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = socketSend.Receive(buffer);
//实际接收到的有效字节数
if (r == 0)
{
break;
}
//表示接收的是文字消息
if (buffer[0] == 0)
{
string s = Encoding.UTF8.GetString(buffer, 1, r - 1);
ShowMsg(socketSend.RemoteEndPoint + ":" + s);
}
else if (buffer[0] == 1)//接收的是文件
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "请选择要保存的文件";
sfd.Filter = "所有文件|*.*";
sfd.ShowDialog(this);
string path = sfd.FileName;
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
fsWrite.Write(buffer, 1, r - 1);
}
MessageBox.Show("保存成功");
}
else if (buffer[0] == 2)//接收的是振动消息
{
ZD();
}
}
catch { }
}
}
//对窗口进行振动
void ZD()
{
for (int i = 0; i < 500; i++)
{
this.Location = new Point(200, 200);
this.Location = new Point(280, 280);
}
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
//关闭客户端,通知服务器断开连接了。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
string str = "断开连接";
byte[] buffer = Encoding.UTF8.GetBytes(str);
try
{
socketSend.Send(buffer);
//断开客户端
socketSend.Shutdown(SocketShutdown.Both);
socketSend.Close();
}
catch (Exception)
{
}
}
}
}