socket 编程实战(编写服务器程序 )

news2024/11/17 17:49:38

IP 地址格式转换函数

对于人来说,我们更容易阅读的是点分十进制的 IP 地址,譬如192.168. 1.110 、192.168.1.50,这其实是一种字符串的形式,但是计算机所需要理解的是二进制形式的 IP 地址,所以我们就需要在点分十进制字符
串和二进制地址之间进行转换。

点分十进制字符串和二进制地址之间的转换函数主要有:inet_aton、inet_addr、inet_ntoa、inet_ntop、inet_pton 这五个,在我们的应用程序中使用它们需要包含头文件<sys/socket.h>、<arpa/inet.h>以及<netinet/in.h>。

inet_aton、inet_addr、inet_ntoa 函数 这些函数可将一个 IP 地址在点分十进制表示形式和二进制表示形式之间进行转换,这些函数已经废弃了,基本不用这些函数了,但是在一些旧的代码中可能还会看到这些函数。完成此类转换工作我们应该使用下面介绍的这些函数。

inet_ntop、inet_pton 函数

inet_ntop()、inet_pton()与 inet_ntoa()、inet_aton()类似,但它们还支持 IPv6 地址。它们将二进制 Ipv4 或Ipv6 地址转换成以点分十进制表示的字符串形式,或将点分十进制表示的字符串形式转换成二进制 Ipv4 或Ipv6 地址。使用这两个函数只需包含<arpa/inet.h>头文件即可!

inet_pton()函数

inet_pton()函数原型如下所示:

int inet_pton(int af, const char *src, void *dst); 

inet_pton()函数将点分十进制表示的字符串形式转换成二进制 Ipv4 或 Ipv6 地址。 将字符串 src 转换为二进制地址,参数 af 必须是 AF_INET 或 AF_INET6,AF_INET 表示待转换的 Ipv4地址,AF_INET6 表示待转换的是 Ipv6 地址;并将转换后得到的地址存放在参数 dst 所指向的对象中,如果参数 af 被指定为 AF_INET,则参数 dst 所指对象应该是一个 struct in_addr 结构体的对象;如果参数 af 被指定为 AF_INET6,则参数 dst 所指对象应该是一个 struct in6_addr 结构体的对象。

inet_pton()转换成功返回 1(已成功转换)。如果 src 不包含表示指定地址族中有效网络地址的字符串,则返回 0。如果 af 不包含有效的地址族,则返回-1 并将 errno 设置为EAFNOSUPPORT。

使用示例

#include<stdio.h>
#include<stdlib.h>
#include<arpa/inct.h>

#define IPV4_ADDR "192.168.1.222"

int main(void)
{
	struct in_addr addr;
	inet_pton(AF_INET,IPV4_ADDR,&addr);
	printf("ip addr:0x%x\n",add.s_addr);
	exit(0);
}

测试结果:
在这里插入图片描述

inet_ntop()函数

inet_ntop()函数执行与 inet_pton()相反的操作,函数原型如下所示:
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

参数 af 与 inet_pton()函数的 af 参数意义相同。

参数 src 应指向一个 struct in_addr 结构体对象或 struct in6_addr 结构体对象,依据参数 af 而定。函数inet_ntop()会将参数 src 指向的二进制 IP 地址转换为点分十进制形式的字符串,并将字符串存放在参数 dts所指的缓冲区中,参数 size 指定了该缓冲区的大小。

inet_ntop()在成功时会返回 dst 指针。如果 size 的值太小了,那么将会返回 NULL 并将 errno 设置为ENOSPC。

#include<stdio.h>
#include<stdlib.h>
#include<arpa/inet.h>

int main(void)
{
	struct in_addr addr;
	char buf[20]={0};
	addr.s_addr = 0xde01a8c0;
	inet_ntop(AF_INET,&addr,buf,sizeof(buf));
	printf("ip addr: %s\n",buf);
	exit(0);
}

测试结果:
在这里插入图片描述

socket 编程实战

经过上面的介绍,本小节我们将进行编程实战,实现一个简单地服务器和一个简单地客户端应用程序。

编写服务器程序

编写服务器应用程序的流程如下:

①、调用 socket()函数打开套接字,得到套接字描述符;

②、调用 bind()函数将套接字与 IP 地址、端口号进行绑定;

③、调用 listen()函数让服务器进程进入监听状态;

④、调用 accept()函数获取客户端的连接请求并建立连接;

⑤、调用 read/recv、write/send 与客户端进行通信;

⑥、调用 close()关闭套接字。

下面,我们就根据上面列举的步骤来编写一个简答地服务器应用程序,代码如下所示:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

#define SERVER_PORT  8888

int main(void)
{
	struct sockaddr_in server_addr = {0};
	struct sockaddr_in client_addr = {0};
	char ip_str[20] = {0};
	int sockfd,connfd;
	int addrlen = sizeof(client_addr);
	char recvbuf[512];
	int ret;
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(0>sockfd)
	{
		perror("socket error");
		exit(EXIT_FAILURE);
	}
	
	server_addr.sin_family = AF_INET; 
	 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
	 server_addr.sin_port = htons(SERVER_PORT); 
	 
	 ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); 
	 if (0 > ret) { 
	 perror("bind error"); 
	 close(sockfd); 
	 exit(EXIT_FAILURE); 
	 } 
	 
	 /* 使服务器进入监听状态 */ 
	 ret = listen(sockfd, 50); 
	 if (0 > ret) { 
	 perror("listen error"); 
	 close(sockfd); 
	 exit(EXIT_FAILURE); 
	 } 
	 
	 /* 阻塞等待客户端连接 */ 
	 connfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen); 
	 if (0 > connfd) { 
	 perror("accept error"); 
	 close(sockfd); 
	 exit(EXIT_FAILURE); 
	 } 
	 
	 printf("有客户端接入...\n"); 
	 inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ip_str, sizeof(ip_str)); 
	 printf("客户端主机的 IP 地址: %s\n", ip_str); 
	 printf("客户端进程的端口号: %d\n", client_addr.sin_port); 
	 
	 /* 接收客户端发送过来的数据 */ 
	 for ( ; ; ) { 
	 
	 // 接收缓冲区清零 
	
	 memset(recvbuf, 0x0, sizeof(recvbuf)); 
	 
	 // 读数据 
	
	 ret = recv(connfd, recvbuf, sizeof(recvbuf), 0); 
	 if(0 >= ret) { 
	 perror("recv error"); 
	 close(connfd); 
	 break; 
	 } 
	 
	 // 将读取到的数据以字符串形式打印出来 
	
	 printf("from client: %s\n", recvbuf); 
	 
	 // 如果读取到"exit"则关闭套接字退出程序 
	
	 if (0 == strncmp("exit", recvbuf, 4)) { 
	 printf("server exit...\n"); 
	 close(connfd); 
	 break; 
	 } 
	 } 
	 
	 /* 关闭套接字 */ 
	 close(sockfd); 
	 exit(EXIT_SUCCESS); 
	} 
}

以上我们实现了一个非常简单地服务器应用程序,根据上面列举的步骤完成了这个示例代码,最终的功能是,当客户端连接到服务器之后,客户端会向服务器(也就是本程序)发送数据,在我们服务器应用程序中会读取客户端发送的数据并将其打印出来,就是这么简单的一个功能。

SERVER_PORT 宏指定了本服务器绑定的端口号,这里我们将端口号设置为 8888,端口不能与其它服务器的端口号发生冲突,不常用的端口号通常大于 5000。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/390434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录第三章读书笔记——数组

一.二分查找前提&#xff1a;数组为有序数组&#xff0c;数组中无重复元素&#xff0c;因为一旦有重复元素&#xff0c;使用二分查找法返回的元素下标可能不是唯一的&#xff0c;这些都是使用二分法的前提条件&#xff0c;当题目描述满足如上条件的时候&#xff0c;可要想一想是…

FPGA的GigE Vision IP相机图像采集方案设计,转换为千兆UDP,支持10G MAC

1 概述 GigE Vision是一个比较复杂的协议&#xff0c;要在FPGA中完全实现具有较大的难度。如果FPGA作为接收端希望实现GigE Vision相机的配置和图像采集功能&#xff0c;则只需要实现其中小部分功能即可。本文对原有GigE Vision协议的结构进行了裁剪&#xff0c;仅保留设备搜索…

Maven基本使用以及IDEA中配置使用的详细介绍

文章目录MavenMaven基本介绍Maven基本使用IDEA配置MavenIDEA配置MavenMaven坐标详解IDEA创建Maven项目IDEA导入Maven项目Maven依赖管理Maven Maven基本介绍 Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来…

GAMES101学习笔记——光栅化

一&#xff1a;什么是光栅化&#xff08;Rasterization&#xff09; 把空间里的物体画在屏幕上。 屏幕由一个个阵列排布的像素点组成&#xff0c;屏幕大小指宽度方向由width个像素点&#xff0c;高度方向由height个像素点。 像素点索引范围&#xff1a;&#xff08;0&#xf…

【Java开发】JUC进阶 03:读写锁、阻塞队列、同步队列

1 读写锁&#xff08;ReadWriteLock&#xff09;&#x1f4cc; 要点实现类&#xff1a;ReentrantReadWirteLock通过读写锁实现更细粒度的控制&#xff0c;当然通过Synchronized和Lock锁也能达到目的&#xff0c;不过他们会在写入和读取操作都给加锁&#xff0c;影响性能&#x…

黑马程序员SSM框架教程之学习笔记1

P44-SpringMVC入门案例 1.在pom.xml中导入坐标springMVC与servlet 2.创建一个SpringMVC控制器类 3.创建springMVC配置文件springMvcCponfig 4.定义一个servlet容器启动配置类&#xff0c;在里面加载spring的配置 5.在pom.xml文件中配置tomcat插件 运行结果显示 P45-springMVC入…

2023-03-05:ffmpeg推送本地视频至lal流媒体服务器(以RTMP为例),请用go语言编写。

2023-03-05&#xff1a;ffmpeg推送本地视频至lal流媒体服务器&#xff08;以RTMP为例&#xff09;&#xff0c;请用go语言编写。 答案2023-03-05&#xff1a; 使用 github.com/moonfdd/ffmpeg-go 库。 先启动lal流媒体服务器软件&#xff0c;然后再执行命令&#xff1a; go…

linux通过nginx映射指定目录文件给外部访问

修改配置文件 #user www-data; #将user www-data;注掉改为root user root; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf;events {worker_connections 768;# multi_accept on; }http {### Basic Settings##sendfile on;tcp_nopush …

【C语言学习笔记】:三子棋具体步骤和代码

一、问题描述 用c语言实现三子棋。 二、基本流程 在写三子棋的代码之前&#xff0c;我们来看看实现这个游戏的逻辑&#xff1a; 1.菜单界面选择开始或者退出游戏。2.创建棋盘并初始化。3.打印棋盘。4.玩家落子(玩家输入行列坐标的方式来落子)&#xff0c;x’表示玩家落子。5…

既然有MySQL了,为什么还要有Redis?

目录专栏导读一、同样是缓存&#xff0c;用map不行吗&#xff1f;二、Redis为什么是单线程的&#xff1f;三、Redis真的是单线程的吗&#xff1f;四、Redis优缺点1、优点2、缺点五、Redis常见业务场景六、Redis常见数据类型1、String2、List3、Hash4、Set5、Zset6、BitMap7、Bi…

ESP32学习笔记01-环境搭建

本文参考博客https://blog.csdn.net/weixin_43599390/article/details/123944479 1.下载离线版本的 ESP IDF esp idf 下载地址 2.安装 esp idf 2.1应用修复,后,再下一步 2.2 2.3 2.4 2.5

跨屏设计规范

跨屏设计规范 以windows10x 为例&#xff0c;其在具体交互上&#xff0c;到底有哪些常见的交互模式和硬件要如何结合 6.1跨平台的双屏交互设计逻辑 这种那个品的设计范式&#xff0c;其实是跨平台的通用规则&#xff0c; 在很大程度上&#xff0c;这套交互逻辑是不受操作系统…

【CSS】CSS 复合选择器 ③ ( 并集选择器 | 并集选择器与后代选择器示例 )

文章目录一、并集选择器1、语法说明2、代码示例二、并集选择器与后代选择器示例1、添加注释2、HTML 结构3、后代选择器 14、后代选择器 25、并集选择器6、完整代码示例7、显示效果一、并集选择器 1、语法说明 并集选择器 可以选择 若干 基础选择器 选择出的 并集元素集合 ; 并集…

【亲测】Centos7系统非管理(root)权限编译NCNN

前言 由于使用的是集群&#xff0c;自己不具有管理员权限&#xff0c;所以以下所有的情况均在非管理员权限下进行安装&#xff0c;即该安装策略仅适用于普通用户构建自己的环境。 什么是NCNN ncnn是一款非常高效易用的深度学习推理框架&#xff0c;支持各种神经网络模型&#x…

文件异步多备常用方案

业务需求上经常存在需要对同一个文件进行双上传&#xff0c;上传到不同云存储桶&#xff0c;以防出现某一个云厂商因各种意外导致自身服务出现不可用的情况&#xff0c;当然&#xff0c;还有其他措施可以避免&#xff0c;现在只针对通过程序业务代码而双写存储的这个场景。 业务…

Java分布式解决方案(三)

文章目录&#x1f525;MySQL事务-MySQL中锁的分类&#x1f525;MySQL事务-MySQL中的死锁问题&#x1f525;MySQL事务-MySQL中锁的分类 MySQL中锁的分类 从本质上讲&#xff0c;锁是一种协调多个进程或多个线程对某一资源的访问的机制&#xff0c;MySQL使用锁和MVCC机制实现了…

了解基本的html和javascript

用记事本编辑一个文本文件&#xff0c;代码如下&#xff0c; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>my name is bo</title> <script>alert(hello); </script> </head> <body>&…

实验2 设计模式实验1

实验内容: 1. 使用简单工厂模式设计一个可以创建不同几何形状(Shape)&#xff0c;例如圆形 (Circle)、矩形(Rectangle)和三角形(Triangle)等的绘图工具类&#xff0c;每个几何图形均具 有绘制方法draw()和擦除方法erase()&#xff0c;要求在绘制不支持的几何图形时&#xff…

Android 基础知识4-3.6 ToggleButton(开关按钮)Switch(开关)详解

一、ToggleButton(开关按钮) 1.1、简介 ToggleButton 类似开关有开和关两种状态&#xff0c;不同的状态下可以有不同的文本。 public class ToggleButton extends CompoundButton Displays checked/unchecked states as a button with a "light" indicator …

CNN基础

Tip&#xff1a;仅供自己学习记录&#xff0c;酌情参考 1. 前馈与反馈神经网络 神经网络有前馈神经网络和反馈神经网络&#xff0c;前向神经网络也就是前馈神经网络。 前馈型神经网络各神经元接收前一层的输入&#xff0c;并输出给下一层&#xff0c;没有反馈。节点分为两类…