网站内容与标题的区别,visual studio2005做网站,wordpress 另类主题,松原手机网站开发公司电话目录
1. 套接字 (Socket)
2. 基于TCP通信的流程
服务器端
客户端
1. TCP通信API
1.1 创建套接字描述符socket
1.2 绑定IP和端口号bind
1.3 设置监听状态 listen
1.4 接受连接请求 accept
1.5 发送数据 send
1.6 接收数据 recv
2. TCP服务器代码示例
代码解释…目录
1. 套接字 (Socket)
2. 基于TCP通信的流程
服务器端
客户端
1. TCP通信API
1.1 创建套接字描述符socket
1.2 绑定IP和端口号bind
1.3 设置监听状态 listen
1.4 接受连接请求 accept
1.5 发送数据 send
1.6 接收数据 recv
2. TCP服务器代码示例
代码解释
注意点 3. 客户端API
连接服务器
功能
参数说明
返回值
示例
代码解释
注意事项 1. 套接字 (Socket) 套接字的本质 socket套接字是一个特殊的文件在原始Linux中它与管道、消息队列、共享内存、信号等机制类似只能用于主机内的进程间通信。 历史发展与通信范围 随着TCP/IP协议族的出现socket套接字能够通过网卡与外部主机进行通信突破了单机限制。 socket函数的作用 调用socket函数会生成一个文件描述符。主机间的不同进程可以通过对该文件描述符的读写实现通信。 2. 基于TCP通信的流程 服务器端 socket 创建原始套接字。 bind 将原始套接字与主机IP绑定该服务器的身份服务器以字节主机的身份通信。 通过bind服务器的套接字被绑定到一个明确的IP地址和端口号。当客户端发起通信请求时客户端通过这个IP地址和端口号找到服务器从而使服务器在网络中以“唯一身份”进行通信。 listen 将原始套接字设置为监听状态。注意监听套接字只能用于监听要进行实际通信需要创建一个新的套接字。 accept 接收客户端的连接请求获取客户端信息并生成一个新的套接字描述符用于与该客户端通信。 通信与关闭 使用新套接字发送和接收信息。完成通信后关闭套接字。
客户端 socket 创建原始套接字。 bind可选 客户端可以选择是否绑定IP和端口号。如果绑定则客户端只能以绑定的IP和端口号进行通信。通常情况下无需绑定除非服务器要求接收特定客户端的信息。 connect 向服务器发送连接请求并携带客户端的身份信息IP和端口号。 通信与关闭 通过套接字发送和接收信息。完成通信后关闭套接字。 1. TCP通信API
1.1 创建套接字描述符socket
#include sys/types.h
#include sys/socket.hint socket(int domain, int type, int protocol);功能创建一个套接字描述符。参数 domain通信域类型 AF_UNIX, AF_LOCAL: 本地通信AF_INET: IPv4通信AF_INET6: IPv6通信type通信类型 SOCK_STREAM: 使用TCP通信协议SOCK_DGRAM: 使用UDP通信协议protocol通常为0表示自动选择与domain和type兼容的协议。返回值成功返回套接字描述符失败返回-1。 1.2 绑定IP和端口号bind
#include sys/types.h
#include sys/socket.hint bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能将套接字与IP和端口绑定指定通信域。参数 sockfd套接字文件描述符。addr通信域的结构体指针通常是struct sockaddr_in其中包含IP地址和端口号。addrlen结构体的大小。返回值成功返回0失败返回-1。 1.3 设置监听状态 listen
#include sys/types.h
#include sys/socket.hint listen(int sockfd, int backlog);功能设置套接字为监听状态等待客户端连接。参数 sockfd套接字描述符。backlog最大等待连接数最多为128。返回值成功返回0失败返回-1。 1.4 接受连接请求 accept #include sys/types.h
#include sys/socket.hint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能从监听队列中接受客户端连接创建新的套接字用于通信。参数 sockfd监听套接字描述符。addr客户端信息结构体struct sockaddr_in接受客户端信息。addrlen客户端信息结构体的大小。返回值成功返回新套接字描述符失败返回-1。 1.5 发送数据 send
#include sys/types.h
#include sys/socket.hssize_t send(int sockfd, const void *buf, size_t len, int flags);功能向其他进程发送数据。参数 sockfd新套接字文件描述符。buf发送的数据缓冲区。len发送的数据长度。flags控制发送的标志例如MSG_DONTWAIT表示非阻塞发送。返回值成功返回发送的字节数失败返回-1。 1.6 接收数据 recv
#include sys/types.h
#include sys/socket.hssize_t recv(int sockfd, void *buf, size_t len, int flags);功能从其他进程接收数据。参数 sockfd新套接字文件描述符。buf接收数据的缓冲区。len接收数据的最大长度。flags控制接收的标志例如MSG_DONTWAIT表示非阻塞接收。返回值成功返回接收的字节数失败返回-1。 2. TCP服务器代码示例 #include myhead.h
#define IP 192.168.60.69
#define PORT 6666
#define BACKLOG 20int main(int argc, const char *argv[])
{// AF_INET: IPV4通信// SOCK_STREAMTCP通信协议int oldfd socket(AF_INET, SOCK_STREAM, 0); // 1. 创建套接字if (oldfd -1){perror(socket);return -1;}// 2. 绑定IP和端口号struct sockaddr_in server {.sin_family AF_INET, // IPV4.sin_port htons(PORT), // 端口号转为网络字节序.sin_addr.s_addr inet_addr(IP), // IP地址};if (bind(oldfd, (struct sockaddr *)server, sizeof(server)) -1){perror(bind);return -1;}// 3. 监听if (listen(oldfd, BACKLOG) -1){perror(listen);return -1;}// 4. 接受客户端连接请求创建新的描述符用于通信struct sockaddr_in client; // 接收客户端信息的结构体socklen_t client_len sizeof(client); // 计算出结构体大小int newfd;newfd accept(oldfd, (struct sockaddr *)client, client_len);if (newfd -1){perror(accept);return -1;}printf(%s发来连接请求\n, inet_ntoa(client.sin_addr));// 5. 循环收发信息char buff[1024];while (1){memset(buff, 0, sizeof(buff));// int len read(newfd, buff, sizeof(buff)); // 传统方式int len recv(newfd, buff, sizeof(buff), 0); // 0: 阻塞发送MSG_DONTWAIT: 非阻塞if (len 0){printf(客户端下线\n);break;}printf(%s\n, buff);strcat(buff, 5201314); // 加上一句话回过去// write(newfd, buff, sizeof(buff)); // 传统方式send(newfd, buff, sizeof(buff), 0); // 发送}close(oldfd);close(newfd);return 0;
}代码解释 创建套接字socket(AF_INET, SOCK_STREAM, 0) 创建一个支持 IPv4 的 TCP 套接字。绑定 IP 和端口通过 bind 函数将服务器的 IP 地址和端口号绑定到创建的套接字上。监听调用 listen 函数将套接字设置为监听状态BACKLOG 指定了等待连接队列的最大长度。接受客户端连接accept 函数用于从等待队列中接收客户端的连接请求返回一个新的套接字文件描述符用于与客户端进行通信。收发信息使用 recv 接收客户端发来的信息并通过 send 发送响应。消息中添加了 5201314 字符串后回传给客户端。关闭套接字完成通信后通过 close 关闭原始套接字和客户端套接字。 注意点 recv 和 send 用于数据传输它们是基于 TCP 协议的保证数据的可靠传输。inet_ntoa 函数用于将客户端的 IP 地址转换为点分十进制格式。使用 strcat 拼接字符串发送回客户端。 3. 客户端API
连接服务器 #include sys/types.h /* See NOTES */
#include sys/socket.hint connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);功能 connect 用于客户端与服务器建立连接。它对应于服务器端的 accept 函数完成了三次握手的过程。客户端通过调用 connect 向服务器发送连接请求服务器通过 accept 接受连接。此时TCP连接的三次握手完成。 参数说明 参数1 (sockfd)套接字描述符即客户端通过 socket 函数创建的套接字。参数2 (addr)服务器的地址结构体包含目标服务器的 IP 地址和端口号。参数3 (addrlen)addr 结构体的大小用于指定服务器地址结构体的大小。 返回值 成功返回 0。失败返回 -1并置位错误码。 示例 #include sys/socket.h
#include arpa/inet.h
#include stdio.h#define SERVER_IP 192.168.60.69
#define SERVER_PORT 6666int main() {int sockfd socket(AF_INET, SOCK_STREAM, 0); // 创建套接字if (sockfd -1) {perror(socket);return -1;}struct sockaddr_in server_addr;server_addr.sin_family AF_INET; // IPV4server_addr.sin_port htons(SERVER_PORT); // 服务器端口server_addr.sin_addr.s_addr inet_addr(SERVER_IP); // 服务器IP// 连接到服务器if (connect(sockfd, (struct sockaddr *)server_addr, sizeof(server_addr)) -1) {perror(connect);return -1;}printf(成功连接到服务器\n);// 这里可以添加发送和接收数据的代码close(sockfd); // 关闭套接字return 0;
}代码解释 创建套接字客户端使用 socket 函数创建一个 TCP 套接字。填充服务器地址结构体struct sockaddr_in 用于定义目标服务器的 IP 地址和端口号。建立连接客户端调用 connect 函数连接到指定服务器。如果连接成功将输出 成功连接到服务器。关闭套接字连接完成后使用 close 关闭套接字。 注意事项 连接过程中的三次握手是自动进行的客户端不需要手动处理三次握手的细节。如果连接失败例如服务器不可达或端口未打开connect 将返回 -1并设置相应的错误码。