Socket

一:介绍一下Socket

程序之间的通讯,使用Socket来连接处理数据,就是一种协议。

1575988667401

二:Socket相关概念

端口:可以认为是设备与外界通讯交流的出口。

IP:又译为网际协议或互联网协议,是用在TCP/IP协议簇中的网络层协议。

协议:TCP/UDP

TCP UDP
速度
是否连接 面向连接(3次握手) 无连接
传输可靠性 安全稳定,效率低 速度快、效率高,不稳定
数据量 少量 大量

三次握手:

(1)在建立通道时,客户端首先要向服务端发送一个SYN同步信号。

(2)服务端在接收到这个信号之后会向客户端发出SYN同步信号和ACK确认信号。

(3)当服务端的ACK和SYN到达客户端后,客户端与服务端之间的这个“通道”就会被建立起来。

三:Socket通信基本流程图

1575989299190

四:代码演示

1.首先我们编写服务器代码,创建负责通讯的Socket绑定对应的IP和端口号,然后进行监听。

1
2
3
4
5
6
7
8
9
10
//创建负责通讯的Socket
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txt_IP.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txt_port.Text));
//获得要连接的远程服务器应用程序的IP地址和端口号
socketSend.Connect(point);
ShowMsg("连接成功!");
//开启线程不断接受信息
Thread t2 = new Thread(Recive);
t2.Start();

2.接受客户端发送的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/// <summary>
/// 轮询接受信息
/// </summary>
/// <param name="o"></param>
void Recive()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = socketSend.Receive(buffer);
int n = buffer[0];
if (r == 0)
{
break;
}
//发送文字消息
if (n == 0)
{
//实际接收到的有效字节数
string str = Encoding.UTF8.GetString(buffer, 1, r-1);
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);

}
else if (n == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = @"C:\Users\Administrator\Desktop";
sfd.Title = "请选择要保存的文件";
sfd.Filter = "所有文件|*.*";
sfd.ShowDialog(this);
string path = sfd.FileName;
using (FileStream fs=new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write))
{
fs.Write(buffer,1,r);
}
}
else if(n==2)
{
ZD();
}


}
catch (Exception)
{
throw;
}
}
}

3.编写客户端:

首先得创建一个Socket对象负责通讯,然后绑定和服务器同一个IP和端口,然后和服务器进行连接。

1
2
3
4
5
6
7
8
9
10
//创建负责通讯的Socket
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txt_IP.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txt_port.Text));
//获得要连接的远程服务器应用程序的IP地址和端口号
socketSend.Connect(point);
ShowMsg("连接成功!");
//开启线程不断接受信息
Thread t2 = new Thread(Recive);
t2.Start();

4.客户端轮询接受服务器的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/// <summary>
/// 轮询接受信息
/// </summary>
/// <param name="o"></param>
void Recive()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = socketSend.Receive(buffer);
int n = buffer[0];
if (r == 0)
{
break;
}
//发送文字消息
if (n == 0)
{
//实际接收到的有效字节数
string str = Encoding.UTF8.GetString(buffer, 1, r-1);
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);

}
else if (n == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = @"C:\Users\Administrator\Desktop";
sfd.Title = "请选择要保存的文件";
sfd.Filter = "所有文件|*.*";
sfd.ShowDialog(this);
string path = sfd.FileName;
using (FileStream fs=new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write))
{
fs.Write(buffer,1,r);
}
}
else if(n==2)
{
ZD();
}


}
catch (Exception)
{
throw;
}
}
}

5.可以进行验证客户机和服务器是否连接成功:

1575990142459

左边是客户端,右边是服务器。

6.客户端和服务端发送信息

1
2
3
        string str = txt_send.Text.Trim();
byte[] buffer = Encoding.UTF8.GetBytes(str);
socketSend.Send(buffer);

1575990451173

7.源码地址