服务器要添加的引用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
客户端要添加的引用:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
<img src="https://img-blog.csdn.net/20140814181746500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZnVsZWkxMTA3NjU1OTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
/// 初始化窗体
/// </summary>
public Form1()
{
InitializeComponent();
}
//声明一个监听Socket
Socket socketWacth;
//声明一个键值对用来存储IP地址及对应的Socket
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
/// <summary>
/// 窗体加载时执行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
//关闭跨线程检查
Control.CheckForIllegalCrossThreadCalls = false;
}
/// <summary>
/// 监听客户端的接入
/// </summary>
private void Watch()
{
while (true)
{
//为新接入的客户端创建一个通信Socket
Socket socketSend = socketWacth.Accept();
//将新接入的客户端IP地址与该客户端Socket绑定存入键值对集合中
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将接入的客户端添加到清单中
lbxIPs.Items.Add(socketSend.RemoteEndPoint.ToString());
//提示客户端接入成功
ShowMsg(socketSend.RemoteEndPoint.ToString() + "已接入");
//通信Socket接收客户端发来的消息
Thread resThread = new Thread(ResMsg);
resThread.IsBackground = true;
resThread.Start(socketSend);
}
}
/// <summary>
/// 开始监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
try
{
//创建一个监听Socket
socketWacth = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//创建一个IP地址对象
IPAddress IP = IPAddress.Parse(txtSeverIP.Text);
//创建一个网络端口对象
IPEndPoint point = new IPEndPoint(IP, Convert.ToInt32(txtDuan.Text));
//将端口绑定监听
socketWacth.Bind(point);
//设置同时能接入的最大数量
socketWacth.Listen(100);
ShowMsg("正在监听...");
//创建一个新线程来执行监听工作
Thread WatchThread = new Thread(Watch);
WatchThread.IsBackground = true;
WatchThread.Start();
}
catch
{
ShowMsg("你输入的IP地址有误");
}
/// <summary>
/// 接收客户端发来的消息并转发给指定客户端
/// 自定义协议,数据第一个字节为0则发送的是IP地址
/// 第一个字节为1则为文字信息
/// 第一个字节为2则为文件信息
/// 第一个字节为3则为震动
/// </summary>
/// <param name="o"></param>
private void ResMsg(object o)
{
Socket socketSend = o as Socket;
string IP = null;
while (true)
{
int r;
//获取当前已连接的客户端IP地址
string IP2 = socketSend.RemoteEndPoint.ToString();
//创建一个缓冲区来存储客户端发来的信息
byte[] buffer = new byte[1024 * 1024 * 3];
try
{
r = socketSend.Receive(buffer);
}
catch
{
ShowMsg(IP2 + "已经下线");
//将该IP地址在集合中删除
dicSocket.Remove(IP2);
//将该IP地址在列表中删除
lbxIPs.Items.Remove(IP2);
return;
}
int number = buffer[0];
if (number == 0)//客户端发来的是IP地址
{
//获得客户端发来的IP地址,该IP地址是客户端要通信的其他客户端IP
IP = Encoding.Default.GetString(buffer, 1, r - 1);
//通过客户端发来的IP地址来找到要进行通信的Socket
//对方不在线就提示对方不在线
//在线就不动,等待用户发送消息给服务器
if (dicSocket.ContainsKey(IP))
{
}
else
{
SendWord(socketSend, "对方不在线!");
}
}
else//客户端发送过来的消息
{
//服务器将发送信息客户端IP地址发送到接收信息的客户端
//将IP地址加上标签
byte[] newBuffer= AddNum(Encoding.Default.GetBytes(IP2), 0);
//将加上标签的IP地址转换成字符串
string IP2new = Encoding.Default.GetString(newBuffer);
try
{
//发送客户端IP地址
SendWord(dicSocket[IP], IP2new);
//将客户端发送过来的消息转发给客户端指定(IP)的客户端
SendWord(dicSocket[IP], Encoding.Default.GetString(buffer, 0, r));
if (number==1)
{
//将客户端动态展示到服务器
ShowMsg(IP2 + "给" + IP + "发送了一条消息");
}
else if (number==2)
{
//将客户端动态展示到服务器
ShowMsg(IP2 + "给" + IP + "发送了一个文件");
}
else if (number==3)
{
//将客户端动态展示到服务器
ShowMsg(IP2 + "给" + IP + "发送了一个抖屏");
}
}
catch
{
SendWord(socketSend, "你他妈在逗我?你都没有选择要发送的好友");
}
}
}
}
/// <summary>
/// 将一个字节数组前面添加表示数字
/// </summary>
/// <param name="buffer">要添加标签的数组</param>
/// <param name="number">标签</param>
/// <returns></returns>
private byte[] AddNum(byte[] buffer, byte number)
{
List<byte> list = new List<byte>();
list.Add(number);
list.AddRange(buffer);
byte[] newBuffer = list.ToArray();
return newBuffer;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="o"></param>
private void SendWord(object o, string str)
{
Socket socketSend = o as Socket;
byte[] buffer = Encoding.Default.GetBytes(str);
//发送信息
socketSend.Send(buffer);
}
/// <summary>
/// 显示服务器消息
/// </summary>
/// <param name="str"></param>
private void ShowMsg(string str)
{
txtMsg.AppendText(str + "\r\n");
}
<pre name="code" class="csharp">//这就把服务器端写好了,添加代码运行,此时正在等待客户端的接入。//下面我开始写客户端的代码,我注释已经写得非常详细了,大家可以根据我上面的思路来理解代码。
//这里有个小问题,由于我开始设置的服务器IP地址跟大家的本机IP地址肯定不一样,大家的修改成本机IP地址后才能启动监听。端口号可以自己修改。