File tree 11 files changed +224
-0
lines changed
11 files changed +224
-0
lines changed Original file line number Diff line number Diff line change
1
+ 网络编程的一些练习,用node.js实现
Original file line number Diff line number Diff line change
1
+ const net = require ( "net" )
2
+
3
+ /**
4
+ * 客户端
5
+ */
6
+ const client = net . Socket ( )
7
+
8
+ //各个客户端的空闲端口
9
+ let clientDict = { }
10
+
11
+ client . connect ( 8082 , '127.0.0.1' , ( ) => {
12
+ console . log ( '连接到服务端' )
13
+
14
+ client . write ( 'client1:8083' )
15
+ } )
16
+
17
+ /*监听服务器传来的data数据*/
18
+ client . on ( 'data' , ( data ) => {
19
+ console . log ( `客户端client1接收消息:${ data . toString ( ) } ` )
20
+ const reg = new RegExp ( / \{ ( .+ ?) \} / g)
21
+ if ( reg . test ( data . toString ( ) ) ) {
22
+ clientDict = JSON . parse ( data . toString ( ) )
23
+ //断开与服务端的连接
24
+ if ( Object . keys ( clientDict ) . length === 2 ) {
25
+ client . destroy ( )
26
+ }
27
+ }
28
+ } )
29
+
30
+ /* 监听end事件 */
31
+ client . on ( "end" , ( ) => {
32
+ console . log ( "data end" )
33
+ } )
34
+
35
+ /**
36
+ * 服务端
37
+ */
38
+ const server = net . createServer ( socket => {
39
+ console . log ( 'someone connects' )
40
+
41
+ /*发送数据*/
42
+ let message = "我是服务端client1"
43
+ socket . write ( message , ( ) => {
44
+ console . log ( `服务端client1发送消息:${ message } ` )
45
+ } )
46
+
47
+ /*接收消息 */
48
+ socket . on ( 'data' , ( data ) => {
49
+ console . log ( `服务端client1接收消息:${ data . toString ( ) } ` )
50
+ } )
51
+ } )
52
+
53
+ server . listen ( 8083 , ( ) => {
54
+ console . log ( 'create server on http://127.0.0.1:8083/' )
55
+ } )
Original file line number Diff line number Diff line change
1
+ const net = require ( "net" )
2
+
3
+ //连接服务端的client
4
+ const client1 = net . Socket ( )
5
+
6
+ //连接client1的client
7
+ const client2 = net . Socket ( )
8
+
9
+ //各个客户端的空闲端口
10
+ let clientDict = { }
11
+
12
+ client1 . connect ( 8082 , '127.0.0.1' , ( ) => {
13
+ console . log ( '连接到服务端' )
14
+
15
+ client1 . write ( 'client2:8084' )
16
+ } )
17
+
18
+ /*监听服务器传来的data数据*/
19
+ client1 . on ( 'data' , ( data ) => {
20
+ console . log ( `客户端client2接收消息:${ data . toString ( ) } ` )
21
+ const reg = new RegExp ( / \{ ( .+ ?) \} / g)
22
+ if ( reg . test ( data . toString ( ) ) ) {
23
+ clientDict = JSON . parse ( data . toString ( ) )
24
+ if ( Object . keys ( clientDict ) . length === 2 ) {
25
+ client1 . destroy ( )
26
+ }
27
+ //当clientDict中包含client1的端口时,client2与client1建立连接
28
+ if ( 'client1' in clientDict ) {
29
+ setTimeout ( ( ) => {
30
+ client2 . connect ( clientDict . client1 , '127.0.0.1' , ( ) => {
31
+ console . log ( '客户端client2连接到服务端client1' )
32
+ client2 . write ( '我是客户端client2' )
33
+ } )
34
+ client2 . on ( 'data' , ( data ) => {
35
+ console . log ( `客户端client2接收消息:${ data . toString ( ) } ` )
36
+ } )
37
+ } , 10000 )
38
+ }
39
+ }
40
+ } )
41
+
42
+ /* 监听end事件 */
43
+ client1 . on ( "end" , ( ) => {
44
+ console . log ( "data end" ) ;
45
+ } )
Original file line number Diff line number Diff line change
1
+ const net = require ( 'net' )
2
+
3
+ //用于存放客户端的数组
4
+ let client = [ ]
5
+
6
+ //用于存放不同客户端空闲端口号的字典
7
+ let clientDict = { }
8
+
9
+ const server = net . createServer ( socket => {
10
+ client . push ( socket )
11
+
12
+ server . getConnections ( ( err , count ) => {
13
+ console . log ( `客户端连接数:${ count } ` )
14
+ } )
15
+
16
+ /*发送数据*/
17
+ let message = "hello clinet! I'm server"
18
+ socket . write ( message , ( ) => {
19
+ console . log ( `服务端发送消息:${ message } ` )
20
+ } )
21
+
22
+ /*监听data事件*/
23
+ socket . on ( 'data' , ( data ) => {
24
+ const msg = data . toString ( ) . split ( ':' )
25
+ console . log ( `服务端接收消息:${ data . toString ( ) } ` )
26
+ clientDict [ msg [ 0 ] ] = msg [ 1 ]
27
+ setTimeout ( ( ) => {
28
+ for ( let i in client ) {
29
+ client [ i ] . write ( JSON . stringify ( clientDict ) , ( ) => {
30
+ console . log ( `服务端群发出端口字典:${ JSON . stringify ( clientDict ) } ` )
31
+ } )
32
+ }
33
+ } , 1000 )
34
+ } )
35
+ } )
36
+
37
+ /*设置连接关闭时的回调函数*/
38
+ server . on ( 'close' , ( ) => {
39
+ console . log ( '连接关闭' )
40
+ } )
41
+
42
+ /*设置监听端口*/
43
+ server . listen ( 8082 , ( ) => {
44
+ console . log ( 'create server on http://127.0.0.1:8082/' )
45
+ } )
Original file line number Diff line number Diff line change
1
+ 开启服务顺序:server-->client2-->client1
2
+
3
+ # 效果展示
4
+
5
+ 服务端server:
6
+
7
+ ![ 1] ( img/1.png )
8
+
9
+ 客户端client1:
10
+
11
+ ![ 2] ( img/2.png )
12
+
13
+ 客户端client2:
14
+
15
+ ![ 4] ( img/4.png )
16
+
17
+ # 执行流程
18
+
19
+ ![ 3] ( img/3.png )
20
+
21
+ - 客户端client1和客户端client2通过端口8082和服务端server进行连接,并将它们空闲的端口发给服务端server
22
+
23
+ - client1还要作为服务端去监听它空闲的端口
24
+
25
+ - 服务端server将与它相连的客户端都放到一个数组里,把每个客户端空闲的端口都放到一个字典里,并把字典群发给每个客户端(通过遍历数组)
26
+
27
+ - 接着客户端client1和客户端client2断开与服务端server的连接
28
+
29
+ - 客户端client2去请求与服务端client1连接,连接后client1与client2可以直接通信
Original file line number Diff line number Diff line change
1
+ # 实验内容:基于服务器的客户端相互直接通信
2
+
3
+ 具体要求包括:
4
+
5
+ 1.Server支持多客户访问;
6
+
7
+ 2.C与S之间使用TCP连接;
8
+
9
+ 3.C与C之间直接通信(不是通过S传递)。
10
+
11
+ 4.C与C之间直接通信既可以使用TCP,也可以使用UDP。
12
+
13
+ 5.可以使用Socket,也可以使用TcpClient/UdpClient等;
14
+
15
+ 6.实验示意图如下:
16
+
17
+ ![ 1] ( img/1.jpg )
18
+
19
+ # 实验提示
20
+
21
+ 1.交换双方的端口号
22
+
23
+ - 教材例子登陆时发送了用户名,可以顺便发送端口号,服务器收到后分发给各个客户。
24
+
25
+ login,UserName,IP: Port
26
+
27
+ - 每个客户端要预先获得一个“可用”的端口号,才能告诉服务器自己监听的端口号。注意此端口号,与连接服务器时获得的动态端口号,不是同一个端口。
28
+
29
+ 2.客户端之间用TCP通信
30
+
31
+ - 每个客户端自己也要充当服务器的角色,监听自己的某个端口等待其他客户来连接------启动监听线程;
32
+
33
+ - 发起会话的一端,可以使用动态端口去连接另一端;
34
+
35
+ - 假如客户C1直接去连接客户C2(此时C2作为服务端),连接建立后C1可以发消息给C2,消息发送后连接是否要保留?
36
+
37
+ - 接上,如果保留连接,C2回发消息给C1,如何处理?
38
+
39
+ - 接上,如果不保留连接,则表示双方每发一次消息,就建立一次连接。
40
+
41
+ 3.客户端之间用UDP通信
42
+
43
+ 每个客户端启动一个收消息的线程即可。问题是,如何知道是谁发过来的消息。
44
+
45
+ 4.编程选择
46
+
47
+ 可以书上例题代码为基础,进行修改;或者继续修改上个实验代码;
48
+
49
+ 客户端c1与c2通过服务器获取相互的端口及用户消息后,关闭服务器可以直接通信。
You can’t perform that action at this time.
0 commit comments