一.几个注意点
1.不允许跨线程访问
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}//在窗口加载时加上 `
2. 多线程的使用
hread th1 = new Thread(Resive); th1.Start(s); th1.IsBackground = true; //变为后台线程 主线程结束时一块结束
3.一个 服务器上的 端口 只有一个负责监听的socket 但每连一个客户端就会有一个 负责通信的socket生成
4.转换成ip地址的时候千万别有空格
二.要实现的功能
客户端连接服务器的ip地址与一个应用程序的端口号 ,互发信息
三.
步骤 服务器的配置
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
Dictionary<string, Socket> dictoryso = new Dictionary<string, Socket>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//创建负责监听的 socket
Socket so = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//必须ipv4荔浦
//创建ip地址和端口类对象
string s = txtServer.Text;
IPAddress ip = IPAddress.Parse(s);
IPEndPoint ioend = new IPEndPoint(ip, int.Parse(txtPort.Text));
//让负责监听的socket绑定端口号
so.Bind(ioend);//监听他
show("监听成功");
so.Listen(10);//设置能连接 这个服务器应用程序的最大数量
Thread th = new Thread(Listen);
th.IsBackground = true;//
th.Start(so);//根据里式转换 父类 对象可以由子类赋值 父类也能转换成父类
}
Socket s;
void Listen(object o) //引用类型
{
Socket so = o as Socket;
while (true)
{
try
{
//让负责 监听的socket 创建一个负责 通信的socket
s = so.Accept();// 一直等待客户端的连接 如果没有就一直卡着
//获取连接端的 IP及端口
dictoryso.Add(s.RemoteEndPoint.ToString(), s);
comboBox1.Items.Add(s.RemoteEndPoint.ToString());
show(s.RemoteEndPoint.ToString());//只要有连接就会 show出来继续执行,如果没有 就停在show
//接收信息
Thread th1 = new Thread(Resive);
th1.Start(s);
th1.IsBackground = true;
}
catch
{
}
}
}
private void Resive(object s1)
{
while (true)
{
try// 防止出异常
{
Socket s = (Socket)s1;
byte[] buffer = new byte[1024 * 1024 * 2]; //只能传二进制 之后再解码
int r = s.Receive(buffer);//把接收的字节放到buffer 里面 并且 返回 字节数
if (r == 0) break;
string str = Encoding.UTF8.GetString(buffer, 0, r); // 解码
txtLog.Clear();
txtLog.Text=str;
}
catch //什么都不用写 出异常只需 不想下执行 ,不用告诉用户
{
}
}
}
private void show(string s)
{
txtLog.AppendText(s);
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
private void txtServer_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
string str = txtMsg.Text;
byte[] buffer = Encoding.UTF8.GetBytes(str);
string ip = comboBox1.SelectedItem.ToString();
dictoryso[ip].Send(buffer);// 一个 监听的生成几个 通信的每一个都有一个socket 发信息要用通信的socket
}
}
}
客户端的配置
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
Socket socketsend;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
socketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(textSever.Text);
IPEndPoint point = new IPEndPoint(ip, int.Parse(textPort.Text));
socketsend.Connect(point);//如果不能连接 就一直卡在这里
Showmsg("连接成功");
Thread th = new Thread(Resive);
th.Start();
}
private void button2_Click(object sender, EventArgs e)//发送消息
{
string str = textMsg.Text;
byte[] buffer = new byte[1024 * 1024];
buffer = Encoding.UTF8.GetBytes(str);
socketsend.Send(buffer);
}
private void textSever_TextChanged(object sender, EventArgs e)
{
}
private void textPort_TextChanged(object sender, EventArgs e)
{
}
private void Showmsg(string str)
{
textMsg.AppendText(str);
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Resive() //接收消息
{
while (true)
{
byte[] buffer = new byte[1024 * 1024];
int r = socketsend.Receive(buffer);//得到后放在 buffer里面
string str = Encoding.UTF8.GetString(buffer,0,r);//解开buffer里面的码// 不写默认全解码
textMsg.Text = str;
}
}
}
}
原文:https://www.cnblogs.com/pursuit-purity/p/14633898.html