本文为大家分享了C#基于Socket套接字的网络通信封装代码,供大家参考,具体内容如下
之所以要进行Socket套接字通信库封装,主要是直接使用套接字进行网络通信编程相对复杂,特别对于初学者而言。实际上微软从.net 2.0开始已经提供了TCP、UDP通信高级封装类如下:
TcpListener
TcpClient
UdpClient
微软从.net 4.0开始提供基于Task任务的异步通信接口。而直接使用socket封装库,很多socket本身的细节没办法自行控制,本文目就是提供一种socket的封装供参考。文中展示部分封装了TCP通信库,UDP封装也可触类旁通:
CusTcpListener
CusTcpClient
TCP服务端封装了服务端本地绑定、监听、接受客户端连接,并提供了网络数据流的接口。完整代码:
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
public
class
CusTcpListener
{
private
IPEndPoint mServerSocketEndPoint;
private
Socket mServerSocket;
private
bool
isActive;
public
Socket Server
{
get
{
return
this
`.mServerSocket; }`
}
protected
bool
Active
{
get
{
return
this
`.isActive; }`
}
public
EndPoint LocalEndpoint
{
get
{
if
(!
`this`.isActive)
{
return
this
`.mServerSocketEndPoint;`
}
return
this
`.mServerSocket.LocalEndPoint;`
}
}
public
NetworkStream DataStream
{
get
{
NetworkStream networkStream =
null
`;`
if
(
`this`.Server.Connected)
{
networkStream =
new
NetworkStream(
`this.Server,` `true
);`
}
return
networkStream;
}
}
public
CusTcpListener(IPEndPoint localEP)
{
this
`.mServerSocketEndPoint = localEP;`
this
`.mServerSocket =
new
Socket(this
.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
}
public
CusTcpListener(
`string
localaddr,
int
port)`
{
if
(localaddr ==
null
`)`
{
throw
new
ArgumentNullException(
`"localaddr"`);
}
this
`.mServerSocketEndPoint =
new
IPEndPoint(IPAddress.Parse(localaddr), port);`
this
`.mServerSocket =
new
Socket(this
.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
}
public
CusTcpListener(
`int
port)`
{
this
`.mServerSocketEndPoint =
new
IPEndPoint(IPAddress.Any, port);`
this
`.mServerSocket =
new
Socket(this
.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
}
public
void
Start()
{
this
`.Start(int
.MaxValue);`
}
/// <summary>
/// 开始服务器监听
/// </summary>
/// <param name="backlog">同时等待连接的最大个数(半连接队列个数限制)</param>
public
void
Start(
`int
backlog)`
{
if
(backlog >
int
`.MaxValue || backlog < 0)`
{
throw
new
ArgumentOutOfRangeException(
`"backlog"`);
}
if
(
`this.mServerSocket ==` `null
)`
{
throw
new
NullReferenceException(
`"套接字为空"`);
}
this
`.mServerSocket.Bind(this
.mServerSocketEndPoint);`
this
`.mServerSocket.Listen(backlog);`
this
`.isActive =
true`;
}
public
void
Stop()
{
if
(
`this.mServerSocket !=` `null
)`
{
this
`.mServerSocket.Close();`
this
`.mServerSocket =
null`;
}
this
`.isActive =
false`;
this
`.mServerSocket =
new
Socket(this
.mServerSocketEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
}
public
Socket AcceptSocket()
{
Socket socket =
this
`.mServerSocket.Accept();`
return
socket;
}
public
CusTcpClient AcceptTcpClient()
{
CusTcpClient tcpClient =
new
CusTcpClient(
`this`.mServerSocket.Accept());
return
tcpClient;
}
}
TCP客户端封装了客户端本地绑定、连接服务器,并提供了网络数据流的接口。完整代码:
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public
class
CusTcpClient : IDisposable
{
public
Socket Client {
get
`;
set`; }
protected
bool
Active {
get
`;
set`; }
public
IPEndPoint ClientSocketEndPoint {
get
`;
set`; }
public
bool
IsConnected {
get
{
return
this
`.Client.Connected; } }`
public
NetworkStream DataStream
{
get
{
NetworkStream networkStream =
null
`;`
if
(
`this`.Client.Connected)
{
networkStream =
new
NetworkStream(
`this.Client,` `true
);`
}
return
networkStream;
}
}
public
CusTcpClient(IPEndPoint localEP)
{
if
(localEP ==
null
`)`
{
throw
new
ArgumentNullException(
`"localEP"`);
}
this
`.Client =
new
Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
this
`.Active =
false`;
this
`.Client.Bind(localEP);`
this
`.ClientSocketEndPoint = localEP;`
}
public
CusTcpClient(
`string
localaddr,
int
port)`
{
if
(localaddr ==
null
`)`
{
throw
new
ArgumentNullException(
`"localaddr"`);
}
IPEndPoint localEP =
new
IPEndPoint(IPAddress.Parse(localaddr), port);
this
`.Client =
new
Socket(localEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);`
this
`.Active =
false`;
this
`.Client.Bind(localEP);`
this
`.ClientSocketEndPoint = localEP;`
}
internal
CusTcpClient(Socket acceptedSocket)
{
this
`.Client = acceptedSocket;`
this
`.Active =
true`;
this
`.ClientSocketEndPoint = (IPEndPoint)this
.Client.LocalEndPoint;`
}
public
void
Connect(
`string
address,
int
port)`
{
if
(address ==
null
`)`
{
throw
new
ArgumentNullException(
`"address"`);
}
IPEndPoint remoteEP =
new
IPEndPoint(IPAddress.Parse(address), port);
this
`.Connect(remoteEP);`
}
public
void
Connect(IPEndPoint remoteEP)
{
if
(remoteEP ==
null
`)`
{
throw
new
ArgumentNullException(
`"remoteEP"`);
}
this
`.Client.Connect(remoteEP);`
this
`.Active =
true`;
}
public
void
Close()
{
this
`.Dispose(true
);`
}
protected
virtual
void
Dispose(
`bool
disposing)`
{
if
(disposing)
{
IDisposable dataStream =
this
`.DataStream;`
if
(dataStream !=
null
`)`
{
dataStream.Dispose();
}
else
{
Socket client =
this
`.Client;`
if
(client !=
null
`)`
{
client.Close();
this
`.Client =
null`;
}
}
GC.SuppressFinalize(
`this`);
}
}
public
void
Dispose()
{
this
`.Dispose(true
);`
}
}
控制台程序试验,服务端程序:
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
class
Program
{
static
void
Main(string[] args)
{
Thread listenerThread =
new
Thread(ListenerClientConnection);
listenerThread.IsBackground =
true
`;`
listenerThread.Start();
Console.ReadKey();
}
private
static
void
ListenerClientConnection()
{
CusTcpListener tcpListener =
new
CusTcpListener(
`"127.0.0.1",` `5100
);`
tcpListener.Start();
Console.WriteLine(
`"等待客户端连接……"`);
while
(
`true`)
{
CusTcpClient tcpClient = tcpListener.AcceptTcpClient();
Console.WriteLine(
`"客户端接入,ip={0} port={1}"`,
tcpClient.ClientSocketEndPoint.Address, tcpClient.ClientSocketEndPoint.Port);
Thread thread =
new
Thread(DataHandleProcess);
thread.IsBackground =
true
`;`
thread.Start(tcpClient);
}
}
private
static
void
DataHandleProcess(object obj)
{
CusTcpClient tcpClient = (CusTcpClient)obj;
StreamReader streamReader =
new
StreamReader(tcpClient.DataStream, Encoding.Default);
Console.WriteLine(
`"等待客户端输入:"`);
while
(
`true`)
{
try
{
string receStr = streamReader.ReadLine();
Console.WriteLine(receStr);
}
catch
(Exception)
{
Console.WriteLine(
`"断开连接"`);
break
`;`
}
Thread.Sleep(
`5`);
}
}
}
客户端程序:
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
class
Program
{
static
void
Main(string[] args)
{
Thread listenerThread =
new
Thread(UserProcess);
listenerThread.IsBackground =
true
`;`
listenerThread.Start();
Console.ReadKey();
}
private
static
void
UserProcess()
{
Console.WriteLine(
`"连接服务器"`);
CusTcpClient tcpClient =
new
CusTcpClient(
`"127.0.0.1",` `5080
);`
tcpClient.Connect(
`"127.0.0.1",` `5100
);`
Console.WriteLine(
`"开始和服务器通信"`);
StreamWriter sw =
new
StreamWriter(tcpClient.DataStream, Encoding.Default);
sw.AutoFlush =
true
`;`
while
(
`true`)
{
for
(
`int
i =
0; i <` `10
; i++)`
{
string str = string.Format(
`"第{0}次,内容:{1}", i,` `"测试通信"
);`
Console.WriteLine(
`"发送数据:{0}"`, str);
sw.WriteLine(str);
}
break
`;`
}
}
}
通信成功:
通过本次封装演示可实现基于Socket的通信库封装,目的就是使用Socket通信库让应用开发人员在进行网络通讯编程时无需关心底层通讯机制,而只关心应用层的开发,让开发变得更简洁。当然UDP封装类似,可自行设计。当然本文只是一种示例,实际使用可使用.net自带封装库或自定义封装。
补充:目前有很多优秀的开源Socket框架,比如SuperSocket、FastSocket等。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
原网址: 访问
创建于: 2023-02-28 15:19:43
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论