#TCP群聊功能实现

 TCP

1. 什么是 TCP?

     TCP (Transmission Control Protocol) 是一个面向连接的、可靠的、字节流服务的传输层协议。它确保所有数据都将从源到目的地无错误地传输,同时也确保数据包按照其发送顺序到达。

2.TCP 的三次握手:

      当 TCP 建立连接时,它会进行所谓的 "三次握手":

<img src="三次握手.png" width="500"/>

SYN: 客户端发送一个 SYN (synchronize) 数据包到服务器,请求连接。

SYN-ACK: 服务器确认客户端的 SYN 请求,并发送一个自己的 SYN 请求加上一个 ACK (acknowledge)。

ACK: 客户端再次发送一个 ACK 数据包给服务器,确认服务器的 SYN 请求。

完成这三个步骤后,连接被建立,数据传输可以开始。

3. TCP 的四次挥手:

     当 TCP 连接关闭时,它会进行所谓的 "四次挥手":

<img src="四次挥手.png" width="500"/>

FIN: 主动方发送一个 FIN (finish) 数据包到被动方,表示它已完成数据发送。

ACK: 被动方接收到 FIN 数据包,并发送一个 ACK 数据包回应。

FIN: 然后,被动方也发送一个 FIN 数据包给主动方,表示它也已完成数据发送。

ACK: 主动方接收到 FIN 数据包,并再次发送一个 ACK 数据包回应。此时,连接被完全关闭。

4.OSI模型

接下来代码TCP群聊实现功能

步骤:

## Node.js 创建 TCP 服务器和客户端

在 Node.js 中提供了 net 模块提供了 TCP 编程 net 模块是 nodejs 核心模块之一

[nodejs net模块文档](https://nodejs.org/dist/latest-v18.x/docs/api/net.html)

[nodejs中文网 net模块文档](https://www.nodejs.com.cn/api/net.html)

### tcp服务端

```js

// 导入

const net = require("net");

// 创建服务端

const server = net.createServer();

// 监听端口

server.listen(9000, "127.0.0.1");

```

### tcp客户端

```js

const net = require('net');

const client = net.createConnection({port: 9000}, () => {

    console.log('链接成功');

});

client.on('data', (data) => {

    console.log(data.toString());

});

----

#事件监听

-----

#### net.Server 事件

1. listening

- 当服务器调用 server.listen() 后绑定端口并开始监听时,触发此事件。

```js

server.on('listening', () => {

    console.log('Server is listening...');

});

2. connection:

- 当有新的连接被建立时,触发此事件。此事件的回调函数会接收到表示该连接的 socket 对象。

```js

server.on('connection', (socket) => {

    console.log('New connection established');

});

3. close:

- 当服务器关闭时,触发此事件。注意,不是当单个连接关闭,而是整个服务器实例关闭时。

```js

server.on('close', () => {

    console.log('Server closed');

});

4. error:

- 当服务器发生异常时,触发此事件。这是捕获和处理服务器相关错误的重要事件。

```js

server.on('error', (err) => {

    console.error('Server error:', err.message);

});

net.Server -> socket 事件 **(注意: 这实际上是在 socket 对象上,不是 server 上)**

1. data:

- 当接到来自客户端的数据时,触发此事件。这通常是在与 connection 事件相关的 socket 上使用的。

```js

server.on('connection', (socket) => {

    socket.on('data', (data) => {

        console.log('Received data:', data.toString());

    });

});

2. end:

- 当另一发送 FIN 包(表示它已完成数据发送)时,触发此事件。

```js

socket.on('end', () => {

    console.log('Other end has sent a FIN packet');

});

3. close:

- 当套接字完全关闭时,触发此事件。此事件的回调可以接收一个布尔值参数,如果为 true 表示套接字是由于传输错误或其他异常而关闭的。

```js

socket.on('close', (hadError) => {

    if (hadError) {

        console.log('Socket closed due to an error');

    } else {

        console.log('Socket closed gracefully');

    }

});

4. error:

- 当套接字发生错误时,触发此事件。

```js

socket.on('error', (err) => {

    console.error('Socket error:', err.message);

});

5. connect:

- 当成功地建立套接字连接后,触发此事件。此事件通常在客户端套接字上更为有用,因为它表示已成功连接到服务器。

```js

socket.on('connect', () => {

    console.log('Successfully connected');

});

```

6. timeout:

- 当套接字闲置超时后,触发此事件。这可以通过 socket.setTimeout() 来设置。

```js

socket.on('timeout', () => {

    console.log('Socket timeout');

});

7. drain:

- 当写缓冲区变为空,可以继续写数据到套接字时,触发此事件。

```js

socket.on('drain', () => {

    console.log('Write buffer is now empty');

});

代码如图所示:

const net = require('net')
const conn = net.createConnection({
    port: 9000,
    host: '127.0.0.1',
    // host:'localhost',
})
conn.on('data', (data) => {
    console.log(data.toString());
})

process.stdin.on('data', (data) => {
    console.log('输入:' + data.toString());
    conn.write(data.toString().trim())
})

const net = require('node:net')
const clientSocketList = [];
const server = net.createServer((clientSocket) => {
    clientSocketList.push(clientSocket);
    clientSocket.on('data', (data) => {
        console.log(`收到数据:${data.toString()}`);
        clientSocketList.forEach((item) => {
            if (item !== clientSocket){
                
                item.write('IP:' + clientSocket.remoteAddress 
                + "端口:" + clientSocket.remotePort 
                + '说:' + data.toString())
            }
        })
    })
    clientSocket.on('error', (err) => {
        console.log(err);
    })
})
server.listen(9000)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Ubuntu中实现TCP群聊可以通过以下步骤实现: 1. 建立一个TCP服务器:使用Python编写TCP服务器,绑定到一个IP地址和端口号。当有客户端连接到该服务器时,服务器将创建一个新的套接字,以便与连接的客户端通信。 2. 实现服务器接收消息:当有客户端通过TCP连接到服务器时,服务器可以监听并接收客户端发送的消息。这可以通过编写一个无限循环来实现,该循环等待客户端发送消息,然后将其广播到所有连接的客户端。 3. 处理并发送客户端消息:当某个客户端想要向群聊发送消息时,应该通过TCP连接到服务器并将该消息广播给所有连接的客户端。服务器将确保该消息被正确处理和发送。 4. 客户端连接到服务器:客户端通过TCP连接到服务器,然后发送和接收消息。客户端可以使用Python编写,需要提供IP地址和端口号连接到服务器。 总之,在ubuntu中实现TCP群聊需要理解TCP协议,以及如何使用Python编写TCP服务器和客户端。务必确保正确处理和发送消息,以确保可以实现成功的群聊功能。 ### 回答2: 在Ubuntu中实现TCP群聊需要使用一个TCP服务器来接收客户端的连接和消息,然后将消息广播给所有连接到服务器的客户端。 首先需要使用Socket API编写一个TCP服务器程序,可以使用C语言或Python等编程语言。服务器程序需要监听一个固定的端口,等待客户端连接。当客户端连接上来后,服务器就需要开启一个新的线程来处理这个客户端的消息,防止阻塞其他客户端的连接。 在客户端,需要先连接到服务器,然后可以发送消息给服务器。服务器收到消息后,需要遍历所有连接的客户端,并且发送消息给客户端。需要注意的是,服务器需要对收到的消息进行解析和处理,比如判断消息类型和内容等。 在实现群聊时,可以创建一个聊天室,每个客户端都可以加入或离开聊天室。当某个客户端发送消息时,服务器则广播这个消息给聊天室内的所有客户端。客户端可以通过指令发送消息或执行其他操作,比如查看在线用户列表或退出聊天室等。 总之,在Ubuntu中实现TCP群聊需要编写服务器程序和客户端程序,并且设计消息的传输格式和处理逻辑。可以根据具体需要自己定制协议和功能。 ### 回答3: 在Ubuntu中实现TCP群聊需要通过编程的方式,在终端使用TCP socket进行通信。以下是实现方法: 1.创建一个主服务器程序,绑定一个IP地址和端口号,并使用socket()系统调用创建套接字。将socket与IP地址和端口号绑定,并使用listen()函数监听连接请求。 2.创建多个子客户端程序,每个程序都使用同样的IP地址和端口号与主服务器程序连接。使用socket()函数进行套接字创建,并使用connect()加入主服务器。 3.当客户端连接时,主服务器将为每个客户端创建一个新的socket,并使用fork()进行进程复制。在子进程中,与客户端建立连接,并使用send()函数将欢迎消息发送给客户端。此后,父进程可以等待下一个客户端的连接请求。 4.客户端程序可以使用socket()函数创建套接字,并使用connect()函数连接到主服务器。一旦建立连接,可以使用recv()函数从主服务器接收消息,并使用send()函数将消息发送到主服务器。 5.在收到消息后,主服务器将消息广播给所有已连接的客户端,使用send()函数将消息发送给每个客户端。 6.客户端收到消息后,将其显示在屏幕上,并等待下一条消息。如果客户端想要退出,可以使用exit()函数从主服务器断开连接。 以上就是在Ubuntu中实现TCP群聊的基本思路和实现方法。在实际实现中,还需要考虑并发性、错误处理和线程安全等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值