首页 » 软件开发 » 一文学会网络编程(函数网络编程客户端指针描述)

一文学会网络编程(函数网络编程客户端指针描述)

落叶飘零 2024-07-24 00:32:28 0

扫一扫用手机浏览

文章目录 [+]

1. socket编程基础

1.1 socket概述

socket(套接字)是网络编程中的一种抽象层,它允许应用程序在不同的计算机之间进行网络通信。
在C语言中,我们可以使用socket API来进行网络编程。

一文学会网络编程(函数网络编程客户端指针描述) 软件开发
(图片来自网络侵删)

1.2 socket创建

在C语言中,使用socket()函数来创建一个socket。
该函数的原型如下:

int socket(int domain, int type, int protocol);domain:指定协议族,如AF_INET(IPv4)、AF_INET6(IPv6)等。
type:指定socket类型,如SOCK_STREAM(流式套接字)、SOCK_DGRAM(数据报套接字)等。
protocol:指定协议,通常设置为0,表示使用默认协议。

1.3 socket地址结构

在C语言中,使用sockaddr结构体来表示socket地址。
对于IPv4地址,通常使用sockaddr_in结构体,如下所示:

struct sockaddr_in { short int sin_family; // 地址族,如AF_INET unsigned short int sin_port; // 端口号 struct in_addr sin_addr; // IP地址 unsigned char sin_zero[8]; // 填充字节,一般为0};

1.4 socket绑定

使用bind()函数将socket绑定到一个地址和端口号上。
该函数的原型如下:

int bind(int sockfd, const struct sockaddr addr, socklen_t addrlen);sockfd:socket文件描述符。
addr:指向sockaddr结构体的指针,用于指定地址和端口号。
addrlen:sockaddr结构体的长度。

1.5 socket监听

对于服务器端的socket,使用listen()函数来监听客户端的连接请求。
该函数的原型如下:

int listen(int sockfd, int backlog);sockfd:socket文件描述符。
backlog:指定队列中最大等待连接数。

1.6 socket接收连接

服务器端使用accept()函数来接收客户端的连接请求。
该函数的原型如下:

int accept(int sockfd, struct sockaddr addr, socklen_t addrlen);sockfd:socket文件描述符。
addr:指向sockaddr结构体的指针,用于获取客户端的地址信息。
addrlen:sockaddr结构体的长度。

1.7 socket连接

客户端使用connect()函数来连接服务器。
该函数的原型如下:

int connect(int sockfd, const struct sockaddr addr, socklen_t addrlen);sockfd:socket文件描述符。
addr:指向sockaddr结构体的指针,用于指定服务器的地址和端口号。
addrlen:sockaddr结构体的长度。

2. 数据传输

2.1 数据发送

使用send()函数来发送数据。
该函数的原型如下:

ssize_t send(int sockfd, const void buf, size_t len, int flags);sockfd:socket文件描述符。
buf:指向要发送的数据缓冲区的指针。
len:要发送的数据长度。
flags:发送标志,通常设置为0。

2.2 数据接收

使用recv()函数来接收数据。
该函数的原型如下:

ssize_t recv(int sockfd, void buf, size_t len, int flags);sockfd:socket文件描述符。
buf:指向接收数据缓冲区的指针。
len:要接收的数据长度。
flags:接收标志,通常设置为0。

3. 高级话题

3.1 非阻塞IO

在C语言中,可以通过设置socket为非阻塞模式来实现非阻塞IO。
使用fcntl()函数来设置socket的属性。
例如,将socket设置为非阻塞模式:

int flags = fcntl(sockfd, F_GETFL, 0);fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

3.2 多路复用

多路复用是一种IO模型,它允许同时监听多个socket,从而实现高效的网络应用程序。
在C语言中,可以使用select、poll和epoll等函数来实现多路复用。

3.2.1 select函数

select函数允许程序监视一组socket,等待其中一个或多个变为可读、可写或发生异常。
该函数的原型如下:

int select(int nfds, fd_set readfds, fd_set writefds, fd_set exceptfds, struct timeval timeout);nfds:监视的socket文件描述符集合中最大文件描述符加1。
readfds:指向可读事件文件描述符集合的指针。
writefds:指向可写事件文件描述符集合的指针。
exceptfds:指向异常事件文件描述符集合的指针。
timeout:指向timeval结构体的指针,用于设置超时时间。

3.2.2 poll函数

poll函数与select类似,也可以用于监视一组socket。
与select相比,poll没有最大文件描述符的限制,并且提供了更丰富的事件类型。
该函数的原型如下:

int poll(struct pollfd fds, nfds_t nfds, int timeout);fds:指向pollfd结构体数组的指针,用于指定要监视的socket和事件。
nfds:要监视的socket数量。
timeout:超时时间,单位为毫秒。

3.2.3 epoll函数

epoll是Linux系统中的一种高性能IO多路复用机制。
与select和poll相比,epoll能够处理大量的socket,并且具有更好的性能。
epoll的相关函数包括epoll_create、epoll_ctl和epoll_wait。

epoll_create:创建一个epoll实例并返回文件描述符。
epoll_ctl:用于向epoll实例中添加、修改或删除要监视的socket。
epoll_wait:等待epoll实例中指定的socket发生事件。

4. 实战案例

下面通过一个简单的echo服务器案例来展示C语言网络编程API的使用。

4.1 echo服务器

echo服务器是一个简单的服务器程序,它接收客户端发送的数据,并将其原样返回给客户端。

4.1.1 服务器端代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 1024int main(int argc, char argv[]) { int serv_sock, clnt_sock; struct sockaddr_in serv_addr, clnt_addr; socklen_t clnt_addr_size; char message[BUF_SIZE]; serv_sock = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(9999); bind(serv_sock, (struct sockaddr)&serv_addr, sizeof(serv_addr)); listen(serv_sock, 5); clnt_addr_size = sizeof(clnt_addr); for (int i = 0; i < 5; i++) { clnt_sock = accept(serv_sock, (struct sockaddr)&clnt_addr, &clnt_addr_size); read(clnt_sock, message, BUF_SIZE); write(clnt_sock, message, strlen(message)); close(clnt_sock); } close(serv_sock); return 0;}

4.1.2 客户端代码

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 1024int main(int argc, char argv[]) { int sock; struct sockaddr_in serv_addr; char message[BUF_SIZE]; sock = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(9999); connect(sock, (struct sockaddr)&serv_addr, sizeof(serv_addr)); printf("Input message: "); fgets(message, BUF_SIZE, stdin); write(sock, message, strlen(message)); read(sock, message, BUF_SIZE);

printf("Message from server: %s", message); close(sock); return 0;}

4.2 运行案例

编译服务器端和客户端代码。
首先运行服务器端程序。
然后运行客户端程序,输入一条消息并按回车。
服务器端将收到客户端的消息,并将其原样返回给客户端。
客户端将显示从服务器端收到的消息。

5. 总结

C语言网络编程API为开发者提供了一种强大、灵活的方式来编写网络应用程序。
通过本文的总结,我们了解了socket编程的基础知识,包括socket的创建、地址结构、绑定、监听、接收连接和连接等。
我们还学习了数据传输的基本函数,如send()和recv(),以及高级话题,如非阻塞IO、多路复用和DNS解析。

C语言网络编程API具有丰富的功能和广泛的应用场景,可以帮助开发者实现高效、可靠的网络通信。
掌握这些API的使用方法,对于进行网络编程的开发者来说至关重要。
希望本文能够为读者提供有价值的信息和指导,帮助大家在网络编程领域取得更好的成果。

标签:

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读3 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0