Skip to content

Commit 2af663f

Browse files
committed
完成实验三
1 parent 264be9b commit 2af663f

File tree

11 files changed

+224
-0
lines changed

11 files changed

+224
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
网络编程的一些练习,用node.js实现

Diff for: 实验三:C-C直接通信实验/client1/client1.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
})

Diff for: 实验三:C-C直接通信实验/client2/client2.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
})

Diff for: 实验三:C-C直接通信实验/img/1.jpg

69 KB
Loading

Diff for: 实验三:C-C直接通信实验/img/1.png

47.4 KB
Loading

Diff for: 实验三:C-C直接通信实验/img/2.png

32.6 KB
Loading

Diff for: 实验三:C-C直接通信实验/img/3.png

19.9 KB
Loading

Diff for: 实验三:C-C直接通信实验/img/4.png

29.7 KB
Loading

Diff for: 实验三:C-C直接通信实验/server/server.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
})

Diff for: 实验三:C-C直接通信实验/解析.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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可以直接通信

Diff for: 实验三:C-C直接通信实验/题目.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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通过服务器获取相互的端口及用户消息后,关闭服务器可以直接通信。

0 commit comments

Comments
 (0)