河源北京网站建设,wordpress邮件发文章,wordpress仿站 技术,物流管理网站建设文章目录 TCP网络编程概述1. TCP协议的特点2. TCP与UDP的差异3. TCP编程流程 TCP网络编程相关函数详解1. socket()#xff1a;创建套接字参数说明#xff1a;返回值#xff1a;示例#xff1a; 2. connect()#xff1a;客户端连接服务器参数说明#xff1a;返回值#x… 文章目录 TCP网络编程概述1. TCP协议的特点2. TCP与UDP的差异3. TCP编程流程 TCP网络编程相关函数详解1. socket()创建套接字参数说明返回值示例 2. connect()客户端连接服务器参数说明返回值示例 3. bind()服务器绑定地址和端口参数说明返回值示例 4. listen()监听连接请求参数说明返回值示例 5. accept()接受客户端连接参数说明返回值示例 6. send()发送数据参数说明返回值示例 7. recv()接收数据参数说明返回值示例 8. close()关闭连接参数说明返回值示例 TCP客户端与服务端的实现案例TCP客户端实现TCP服务器实现 TCP网络编程概述
TCPTransmission Control Protocol传输控制协议是一种面向连接的传输层协议广泛应用于网络通信。与UDPUser Datagram Protocol用户数据报协议不同TCP提供了可靠的数据传输机制确保数据能够完整、有序地从发送端传输到接收端。本文将详细介绍TCP协议的特点、TCP与UDP的差异、TCP编程流程以及客户端和服务器的实现方式。
1. TCP协议的特点
TCP具有以下主要特点
面向连接在通信前TCP必须先建立连接。有序号和确认机制每个数据包都带有序号接收方需要发送确认序号确保数据有序接收。排序、检错和失败重传TCP对接收到的数据进行排序检查数据的完整性如有错误会进行重传。大文件传输由于TCP能够分片并重新组装数据包它特别适合大文件的可靠传输。不支持广播和多播与UDP不同TCP不支持广播和多播只支持点对点通信。
在TCP通信中客户端和服务器的角色各不相同
TCP客户端主动向服务器发起连接。TCP服务器被动等待客户端连接。
2. TCP与UDP的差异
特点TCPUDP面向连接是否可靠传输是否顺序保证是否传输效率较低需要连接、确认等较高无连接、无确认数据传输大小限制无有单个数据包有限制广播/多播支持否是
TCP更适合需要可靠传输的应用场景如文件传输、邮件等而UDP更适合实时性要求高的应用如视频、语音传输。
3. TCP编程流程
编写TCP程序时主要流程如下
创建套接字使用socket()函数创建TCP套接字。连接服务器客户端或绑定端口并监听连接服务器。发送或接收数据通过send()和recv()函数进行数据交换。关闭连接使用close()函数关闭套接字。 TCP网络编程相关函数详解
在编写TCP程序时通常会使用一系列网络函数来创建套接字、建立连接、发送/接收数据并关闭连接。下面将对TCP网络编程中常用的函数进行详细讲解以帮助读者更好地理解每个函数的用途及其使用方法。
1. socket()创建套接字
socket()函数是网络编程的基础用于创建套接字Socket。套接字是网络通信的端点类似于两台设备之间的通信通道。它的定义如下
int socket(int domain, int type, int protocol);参数说明
domain指定通信使用的地址族常用的有 AF_INETIPv4网络协议。AF_INET6IPv6网络协议。 type指定套接字类型常用的有 SOCK_STREAM流式套接字用于TCP连接。SOCK_DGRAM数据报套接字用于UDP连接。 protocol一般为0表示使用默认协议TCP或UDP。
返回值
成功返回套接字的文件描述符。失败返回-1并设置errno。
示例
int sock socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
if (sock 0) {perror(socket creation failed);
}2. connect()客户端连接服务器
connect()函数用于客户端主动向服务器发起连接请求。在TCP连接中客户端通过该函数连接指定的服务器。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数说明
sockfd客户端套接字描述符。addr服务器的地址结构通常为struct sockaddr_in。addrlen地址结构的大小。
返回值
成功返回0。失败返回-1并设置errno。
示例
struct sockaddr_in server_addr;
server_addr.sin_family AF_INET;
server_addr.sin_port htons(8000); // 服务器端口号
server_addr.sin_addr.s_addr inet_addr(10.35.184.221); // 服务器IP地址if (connect(sock, (struct sockaddr *)server_addr, sizeof(server_addr)) ! 0) {perror(connect failed);
}3. bind()服务器绑定地址和端口
bind()函数用于将套接字绑定到指定的IP地址和端口号。服务器需要通过bind()来指定其服务的地址和端口。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数说明
sockfd服务器套接字描述符。addr服务器地址结构通常为struct sockaddr_in。addrlen地址结构的大小。
返回值
成功返回0。失败返回-1并设置errno。
示例
struct sockaddr_in server_addr;
server_addr.sin_family AF_INET;
server_addr.sin_port htons(9000); // 绑定端口9000
server_addr.sin_addr.s_addr htonl(INADDR_ANY); // 绑定本机所有IPif (bind(sock, (struct sockaddr *)server_addr, sizeof(server_addr)) ! 0) {perror(bind failed);
}4. listen()监听连接请求
服务器通过listen()函数来监听客户端的连接请求进入监听状态准备接受客户端的连接。
int listen(int sockfd, int backlog);参数说明
sockfd服务器套接字描述符。backlog连接队列的大小表示服务器可以处理的等待连接的客户端数量。
返回值
成功返回0。失败返回-1并设置errno。
示例
if (listen(sock, 5) ! 0) { // 最大连接等待队列长度为5perror(listen failed);
}5. accept()接受客户端连接
accept()函数用于服务器从连接队列中取出一个客户端连接生成一个新的套接字用于和该客户端进行通信。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);参数说明
sockfd服务器监听套接字。addr客户端地址结构用于存储连接的客户端信息。addrlen地址结构的大小。
返回值
成功返回一个新的已连接套接字描述符用于与客户端通信。失败返回-1并设置errno。
示例
struct sockaddr_in client_addr;
socklen_t client_len sizeof(client_addr);
int client_sock accept(sock, (struct sockaddr *)client_addr, client_len);
if (client_sock 0) {perror(accept failed);
}6. send()发送数据
send()函数用于向指定的套接字发送数据。
ssize_t send(int sockfd, const void *buffer, size_t length, int flags);参数说明
sockfd套接字描述符。buffer指向需要发送数据的缓冲区。length要发送的数据长度。flags通常为0可选其他标志位。
返回值
成功返回发送的字节数。失败返回-1并设置errno。
示例
char message[] Hello, TCP Server!;
if (send(sock, message, strlen(message), 0) 0) {perror(send failed);
}7. recv()接收数据
recv()函数用于从指定的套接字接收数据。
ssize_t recv(int sockfd, void *buffer, size_t length, int flags);参数说明
sockfd套接字描述符。buffer指向接收数据的缓冲区。length缓冲区大小。flags通常为0可选其他标志位。
返回值
成功返回接收到的字节数。失败返回-1并设置errno。如果连接被关闭返回0。
示例
char buffer[128];
ssize_t bytes_received recv(sock, buffer, sizeof(buffer), 0);
if (bytes_received 0) {buffer[bytes_received] \0; // 确保数据是以字符串形式输出printf(Received data: %s\n, buffer);
} else if (bytes_received 0) {printf(Connection closed by peer\n);
} else {perror(recv failed);
}8. close()关闭连接
close()函数用于关闭指定的套接字释放相关资源。
int close(int sockfd);参数说明
sockfd需要关闭的套接字描述符。
返回值
成功返回0。失败返回-1并设置errno。
示例
close(sock); // 关闭套接字TCP客户端与服务端的实现案例
TCP客户端实现
在TCP客户端编程中客户端主动发起与服务器的连接。以下是一个基本的TCP客户端代码示例
#include arpa/inet.h
#include sys/socket.h
#include netinet/in.h
#include stdio.h
#include unistd.h
#include string.htypedef struct sockaddr_in addr_in;
typedef struct sockaddr addr;int main(int argc, char const *argv[]) {// 创建TCP套接字int sock socket(AF_INET, SOCK_STREAM, 0);// 连接TCP服务器addr_in server_addr;server_addr.sin_family AF_INET;server_addr.sin_port htons(8000);server_addr.sin_addr.s_addr inet_addr(10.35.184.221);if (connect(sock, (addr *)server_addr, sizeof(server_addr)) ! 0) {perror(connect);return -1;}printf(TCP server connect OK\n);// 每2秒发送一次数据int n 0;while (1) {char data[] hi, tcp server!;if (send(sock, data, strlen(data), 0) 0) {printf((%d)发送成功\n, n);}sleep(2);}close(sock);return 0;
}TCP服务器实现
TCP服务器是被动的等待客户端连接。在实现中服务器需要首先绑定地址并监听客户端连接接着通过accept()函数接受客户端的连接。以下是一个简单的单聊TCP服务器实现
#include arpa/inet.h
#include sys/socket.h
#include netinet/in.h
#include stdio.h
#include unistd.h
#include string.h
#include pthread.h
#include stdlib.htypedef struct sockaddr_in addr_in;
typedef struct sockaddr addr;typedef struct {int sock;char ip[INET_ADDRSTRLEN];
} client_info;void *readTask(void *arg) {client_info *info (client_info *)arg;while (1) {char buf[128] ;ssize_t len recv(info-sock, buf, 128, 0);if (len 0) {printf(%s: %s\n, info-ip, buf);}}
}void *sendTask(void *arg) {client_info *info (client_info *)arg;while (1) {char buf[128] ;fgets(buf, 128, stdin);buf[strlen(buf)-1] 0;send(info-sock, buf, strlen(buf), 0);if (strncmp(buf, bye, 3) 0) break;}
}int main(int argc, char const *argv[]) {if (argc ! 2) return -1;// 创建TCP套接字int sock socket(AF_INET, SOCK_STREAM, 0);// 设置服务器地址addr_in server_addr;server_addr.sin_family AF_INET;server_addr.sin_port htons(atoi(argv[1]));server_addr.sin_addr.s_addr htonl(INADDR_ANY);if (bind(sock, (addr *)server_addr, sizeof(server_addr)) ! 0) {perror(bind);return -1;}listen(sock, 1000);printf(TCP server running\n);addr_in client_addr;socklen_t client_addr_len sizeof(client_addr);int client_sock accept(sock, (addr *)client_addr, client_addr_len);if (client_sock 0) {client_info info;info.sock client_sock;inet_ntop(AF_INET, client_addr.sin_addr, info.ip, INET_ADDRSTRLEN);printf(Client connected: %s\n, info.ip);pthread_t read_tid, send_tid;pthread_create(read_tid, NULL, readTask, info);pthread_create(send_tid, NULL, sendTask, info);pthread_join(send_tid, NULL);}close(sock);return 0;
}通过上述TCP网络编程的介绍和实例代码读者可以掌握如何使用TCP协议进行可靠的数据通信并根据实际需求实现功能丰富的网络应用程序。