服务端:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace 服务端
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;//监听设置了线程,不让主线程知道,否则主线程做两件事就出错
}
private void label1_Click(object sender, EventArgs e)
{
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
//当点击开始监听的时候,在服务器端创建一个负责监听IP地址跟端口的Socket
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Any;// 提供监听所有客户端IP
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtport.Text));//绑定IP和端口
socketWatch.Bind(point);//绑定监听
socketWatch.Listen(10);//设置监听列队
ShowMsg("开始监听");
Thread th = new Thread(Listen);//创建线程
th.IsBackground = true;//设为后台线程
th.Start(socketWatch);//告诉CPU 监听的socketWatch线程准备好了.
}
void ShowMsg(string str)
{
txtlog.AppendText(str + "\r\n");
}
/// <summary>
/// 等待客户端连接,并且创建与之通信的Socket
/// </summary>
///
Socket socketSend;
void Listen(object o) //调用这个方法的时候把o做为参数调进来
{
Socket socketWatch = o as Socket; //as把o强转为Socket,如果成功为true,否则为空
while (true)
{
socketSend = socketWatch.Accept();//负责和客户端通信的socketSend
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");//拿到客户端的IP和端口
//将远程连接的客户端的IP地址和Socket存入键值集合中
dicsocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将远程连接的客户端的IP地址和Socket存入下拉框中
cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
Thread th = new Thread(Recive);//创建Recive线程接收客户端的数据
th.IsBackground = true;//设为后台线程
th.Start(socketSend);//告诉CPU 监听的socketSend线程准备好了.
}
}
/// <summary>
/// 服务端不停的接收客户端发来的消息
/// </summary>
/// <param name="o"></param>
///
void Recive(object o)
{
Socket socketSend = o as Socket; //as把o强转为Socket,如果成功为true,否则为空
while (true)//循环接收用户的数据
{
byte[] buffer = new byte[1024 * 1024 * 2]; //建立缓冲区
int r = socketSend.Receive(buffer);//接收到的数据存到缓冲区,并返回int 值
if (r == 0)//判断接收的数据是空那么就关闭,否则一直循环空消息
{
break;
}
//用UTF8解码传过来的数字从0开始到r结束
string str = Encoding.UTF8.GetString(buffer, 0, r);
//解码完成添加到txtlog
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
try
{
}
catch (Exception)
{
throw;
}
}
//创建键值对集合,将远程连接的客户端的IP地址和Socket存入键值集合中
Dictionary<string, Socket> dicsocket = new Dictionary<string, Socket>();
private void button4_Click(object sender, EventArgs e)
{
string str = txtMsg.Text.Trim();//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();
//获得用户在下拉框cboUsers中的IP地址和端口
string ip = cboUsers.SelectedItem.ToString();
dicsocket[ip].Send(newBuffer);
// socketSend.Send(buffer);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
客户端:
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;
namespace 客户端
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;//监听设置了线程,不让主线程知道,否则主线程做两件事就出错
}
Socket socketSend;//创建负责连接的Socket
/// <summary>
/// 连接服务器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//当点击开始监听的时候,在服务器端创建一个负责监听IP地址跟端口的Socket
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtServer.Text);//IP地址
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtport.Text));//绑定IP和端口
socketSend.Connect(point);//连接远程服务器应用程序的IP和端口
ShowMsg("连接成功");
//开启一个新的线程,不停的接收服务端发来的消息
Thread th = new Thread(Recive);
th.IsBackground = true;
th.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
}
void ShowMsg(string str)
{
textBox3.AppendText(str + "\r\n");
}
/// <summary>
/// 客户端不停的接收服务端发来的消息
/// </summary>
/// <param name="o"></param>
void Recive(object o)
{
while (true)
{
byte[] buffer = new byte[1024 * 1024 * 3];//声明字节数组
int r = socketSend.Receive(buffer);
if (r == 0)
{
break;
}
//0表示接收到文字消息
if (buffer[0] == 0) //文字消息处理
{
string str = Encoding.UTF8.GetString(buffer, 1, r - 1);
ShowMsg(socketSend.RemoteEndPoint + ":" + str);
}
}
}
/// <summary>
/// 客户端给服务器发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
string str = txtMsg.Text.Trim();//客户端要发送到服务器的消息,集中到字符串
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);//将文本字符串转为字节
socketSend.Send(buffer);//发送字节到已连接服务器
}
private void button3_Click(object sender, EventArgs e)
{
socketSend.Close();
}
}
}