TCP编程详解

发布时间:2023-05-20

TCP编程相关内容

一、TCP编程思政

TCP(Transmission Control Protocol)是一种面向连接的协议,通常用于可靠的数据传输。在互联网中,TCP是应用最广泛的传输层协议之一,TCP编程也是网络编程中必须学习的一部分。 而作为一名优秀的编程工程师,需要具备良好的思政能力。TCP编程并不仅仅是一种技术,而更是一种传递信息和交流的方式,需要我们牢记网络安全、规范和道德等多方面的要求,保障网络交流的有效、安全和顺畅。

二、TCP/IP网络编程

TCP/IP是Internet协议族中最基本、最常用的协议之一。TCP/IP网络编程也就成为了网络编程的基础。TCP/IP网络编程的实现过程基于Socket和网络套接字,可以实现进程间通信及跨网络的通信。通过TCP/IP网络编程可以实现同一台计算机上的进程之间的通信,也可以实现不同计算机之间的通信。

三、TCP编程实际步骤

进行TCP编程的实际步骤如下:

  1. 创建一个 Socket 实例
  2. 绑定 IP 和端口
  3. 监听连接
  4. 接受连接
  5. 发送数据
  6. 接收数据
  7. 关闭 Socket

四、TCP编程语言排名

TCP编程可用于多种编程语言,但不同编程语言的实现方式略有区别。如下表列出了一些常用编程语言的TCP编程使用率,仅供参考:

  • C语言:71%
  • Java:10%
  • Python:4%
  • C#:3%
  • PHP:2%
  • ...

五、TCP编程C语言

C语言是TCP编程使用最为广泛的语言之一,许多网络协议的实现都采用C语言。以下为C语言实现TCP客户端的基本步骤,供参考: (1)创建套接字:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

(2)服务器的地址和端口,客户端通过它进行连接:

struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8000);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

(3)连接服务器:

connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

(4)发送数据:

send(sockfd, data, sizeof(data), 0);

(5)接收数据:

recv(sockfd, buffer, sizeof(buffer), 0);

(6)关闭套接字:

close(sockfd);

六、TCP编程在服务器的流程

TCP编程服务器端主要包括以下步骤: (1)创建服务器Socket,指定协议和端口号:

int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8000);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

(2)监听客户端请求:

listen(sockfd, 128);

(3)建立客户端连接:

struct sockaddr_in client_addr;
socklen_t client_addr_length = sizeof(client_addr);
int clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_addr_length);

(4)接收客户端消息:

recv(clientfd, buf, sizeof(buf), 0);

(5)向客户端发送消息:

send(clientfd, msg, strlen(msg), 0);

(6)关闭客户端Socket,断开连接:

close(clientfd);

七、TCP编程流程

TCP编程需要按照以下基本流程进行:

  1. 创建Socket:使用socket()函数创建Socket,获取Socket描述符。
  2. 绑定Socket:使用bind()函数设计Socket的IP地址和端口号。
  3. 监听Socket:使用listen()函数监听Socket端口,等待客户端连接请求。
  4. 接受连接:使用accept()函数接受客户端连接请求,获取到新的Socket到套接字描述符。
  5. 接收数据:使用recv()函数接收客户端请求的数据或信息。
  6. 发送数据:使用send()函数将服务端感兴趣的信息发送给客户端。
  7. 关闭Socket:使用close()函数关闭Socket连接,释放Socket资源。

八、TCP编程Socket阻塞函数

Socket在进行TCP编程时,阻塞是非常常见的现象。以下为两种常见的阻塞函数解决方法: (1)阻塞函数一:accept()
accept()函数会一直等待客户端连接,在没有连接到来的情况下会一直阻塞。解决方法是设定接收客户端连接请求的超时时间。例如:

struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

(2)阻塞函数二:send()recv()
send()recv()函数在数据未准备好时也会发生阻塞,甚至会一直阻塞。解决方法是使用非阻塞I/O,即在socket调用时加入O_NONBLOCK属性(使用位运算)。例如:

fcntl(sockfd, F_SETFL, O_NONBLOCK);

九、TCP编程聊天室

TCP编程可以实现多人在线聊天室,以下是一个简单的聊天室实现:

①服务端:

  1. 创建Socket,绑定IP地址和端口号,监听连接请求;
  2. 接收客户端连接并加入socket列表,同时开辟线程阻塞接收socket数据;
  3. 将客户端发送的消息分析并广播给所有在线客户端;
  4. 当客户端离线时,从socket列表中删除该客户端;

②客户端:

  1. 建立TCP连接;
  2. 开辟线程阻塞接收服务端socket数据;
  3. 向服务端发送消息;
  4. 退出聊天室并关闭socket连接;
    具体实现过程详见附录代码。