Linux网络编程 socket编程篇(一) socket编程基础

目录

一、预备知识 

1.IP地址

2.端口号

3.网络通信

4.TCP协议简介

5.UDP协议简介

6.网络字节序

二、socket

1.什么是socket(套接字)?

2.为什么要有套接字?

3.套接字的主要类型

拓】网络套接字

三、socket API

1.socket API是什么?  

2.为什么要有Socket API?

3.Socket编程常见API

3.1 socket()

int socket(int domain, int type, int protocol); 

3.2 bind()

3.3 listen ()

3.4 accept()

3.5 connect ()

四、sockaddr

1. 是什么?

2. 为什么?

3. sockaddr的分类

4.Linux中sockaddr的声明

5.创建并填充struct sockaddr_in

6.使用sockaddr传参


一、预备知识 

1.IP地址

1.1 是什么?

        IP地址是在IP协议中, 用来标识网络中不同主机的地址。


1.2 IPv4 & IPv6

  • 对于IPv4来说, IP地址是一个4字节, 32位的整数。通常使用 "点分十进制" 的字符串表示IPv4地址, 例如 123.145.67.89 ; 用点分割的每一个数字表示一个字节, 范围是 0 - 255;
  • 对于IPv6来说, IP地址长度为16字节128位,是IPv4地址长度的4倍。于是IPv4点分十进制格式不再适用,采用十六进制表示。具体表示方式请看:IPv6- 百度百科

1.3源IP和目的IP

  • 在IP数据报(在网络层向数据链路层传递数据时封装)的首部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址。
  • 源IP地址:发送消息的主机地址。
  • 目的IP地址:接收消息的主机地址。

2.端口号

2.1 是什么?

         端口号是一个2字节16位的整数,用来标识一个进程。

2.2 pid 表示唯一一个进程; 端口号也是唯一表示一个进程. 那么这两者之间是怎样的关系?

        
  • "端口号" 和 "进程pid"没有任何关系。
    端口号用于网络通信,而进程pid用于进程管理,网络通信和进程管理是两个毫不相干的模块。之所以不用pid来代替端口号的功能是为了功能解耦,减少系统的耦合度。
  • 不是所有的进程需要端口号,但是所有的进程都需要PID。
  • 一个进程可以有多个端口号; 但一个端口号只能被一个进程占用。

2.3 理解源端口号和目的端口号

  • 传输层协议(TCPUDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号。 就是在描述 "数据是谁发的, 要发给谁"。
  • 源端口号:发送消息的进程的端口号。
  • 目的端口号:接收消息的进程的端口号。

3.网络通信

3.1 是什么?

        网络通信的本质就是进程间通信。


3.2 为什么?

        发送数据的主机由进程发出数据,接收数据的主机也要靠进程处理数据。简化后其实就是一个进程发出数据,另一个进程处理数据。所以说网络通信的本质就是进程间通信。


3.3 网络通信时如何保证IP地址+端口号能找到指定进程?

  • 客户端进程给服务端进程发信息
            服务端进程一般都是一经启动,避免关闭,所以服务端进程的端口号不会随意改变。所以客户端进程能根据下载软件时得到的IP地址+端口号找到服务端进程。     
  • 服务端进程给客户端进程发信息
            软件被用户打开后,客户端进程和端口号被创建,此时客户端进程要先向服务端发信息来获取数据,所以服务端进程就得到了客户端进程的IP地址+端口号,往后服务端进程能根据客户端进程的IP地址+端口号找到客户端进程。(所以我们打开软件后,通常会加载一会)

3.4 OS如何根据端口号找到指定的进程?

        底层采用哈希的方式建立了端口号和进程PID或PCB之间的映射关系,当底层拿到端口号时就可以在哈希表中根据端口号找到对应的进程。


3.5 网络通信是双方的

        当一台主机发送数据给另一台主机时,发送方除了要发送数据外还要把自己的 IP地址和端口号 发送给接收方,所以接收方能给发送方回数据。所以说通信是双方的。


4.TCP协议简介

  • TCP(Transmission Control Protocol 传输控制协议),TCP协议是一种有连接、可靠、面向字节流的传输层通信协议
  • TCP协议是面向连接的,如果两台主机之间想要进行数据传输,那么必须要先建立连接,当连接建立成功后才能进行数据传输。
  • TCP协议是可靠的,因为TCP协议注重丢包率, TCP协议花费大量开销解决数据在传输过程中出现的丢包、乱序等问题,保证不丢包。文件传输、电子邮件、网站访问一般用的就是TCP协议。

5.UDP协议简介

  • UDP(User Datagram Protocol 用户数据报协议),UDP协议是一种无连接、不可靠、面向数据报的传输层通信协议。
  • 使用UDP协议进行通信时无需建立连接,如果两台主机之间想要进行数据传输,那么直接将数据发送给对端主机就行了。
  • UDP协议是不可靠的,因为UDP协议注重效率,没有处理在传输数据过程中小概率出现的丢包、乱序等情况。直播一般用的就是UDP协议。

6.网络字节序

6.0 大端字节序和小端字节序

  • 大端字节序:是将数据的低位字节放到高地址处,高位字节放到低地址处。
    地址字节:“大弟高”)
  • 小端字节序,是将数据的低位字节放到低地址处,高位字节放到高地址处。
    地址字节:“小弟弟”)

6.1 是什么?

        
        即网络通信中共同遵守的字节序,规定为 大端字节序(低字节,高地址)

6.2 为什么?

不同计算机的 字节序不同,如果在网络通信时不加以规定,会出现发送方以大端模式发送数据,接收方以小端模式读取数据,导致通信失败的情况。

6.3 怎么定义?

        TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据。
如果当前发送主机是小端, 就需要先将数据转成大端再发送,否则直接发送。

6.4 网络字节序与主机字节序之间的转换函数

        为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换

#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);
//将主机字节序(h)转换为(to)网络字节序(n)要转化的数据是长整数(l)。uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • 这些函数名很好记:h表示host,n表示network,l表示32位长整数,s表示16位短整数。所以htonl表示:将主机字节序(h)转换为(to)网络字节序(n)要转化的数据是长整数(l)。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回
  • 如果主机是大端字节序,这些 函数不做转换将参数原封不动地返回。 

二、socket

1.什么是socket(套接字)

        IP地址+端口号就是socket(套接字) ,用来标定某主机上的某进程。

2.为什么要有套接字?

        有了套接字,不同主机的进程才能在网络中找到彼此,才能进行网络通信(进程间通信的前提是能互相看到彼此),所以说套接字是网络通信的基石。其次有了套接字,开发者才能开发出通用的网络通信接口,用户也能拿着套接字去使用这些接口。


3.套接字的主要类型

  • 网络套接字:应用于跨主机网络通信,也支持本地通信,主要有两种:
         a.流套接字:用于读取TCP协议的数据。
         b.数据报套接字:用于读取UDP协议的数据。
  • unix域间套接字:只能进行本地通信。
  • 原始套接字(SOCK_RAW):可以从应用层直接绕开传输层,直接去访问底层协议,所以原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接字。

拓】网络套接字

  1. 流套接字(SOCK_STREAM)流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因TCP协议。流套接字只能读取TCP协议的数据
  2. 数据报套接字(SOCK_DGRAM)数据报套接字提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP( User DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。数据报套接字只能读取UDP协议的数据。

拓】功能强大的套接字

        套接字是非常强大的,虽然现在主要用于网络通信,但其实套接字可以用于几乎任何类型的进程间通信:本地通信、各种类型的网络通信等。


三、socket API

1.socket API是什么?  

        是提供给程序员(应用层)做网络开发所用的接口,用来实现不同主机中进程的通信。

        Socket API(套接字编程接口)实际是 传输层 提供给 应用层 的编程接口,用来实现不同主机中进程的通信:传输层网络层的基础上提供进程到进程问的逻辑通道,而应用层的进程则利用传输层向另一台主机的某一进程通信。Socket就是应用层与传输层之间的桥梁,使用Socket编程可以开发客户端和服务端应用程序,从而通过网络实现在全球范围内通信。


2.为什么要有Socket API?

        socket(套接字)只是网络通信的前提,只有开发出一套通用的网络接口才能实现不同主机中进程的通信。Linux下的这套接口就是Socket API(套接字编程接口)。


3.Socket编程常见API

3.1 socket()

int socket(int domain, int type, int protocol); 

//创建socket_fd(套接字 文件描述符),用于TCP/UDP网络程序中的客户端 + 服务器

3.2 bind()

//让 socket_fd和sockaddr_in绑定 用于 TCP/UDP 网络程序中的 服务器。

3.3 listen ()

//开始监听socket,用于 TCP 网络程序中的 服务器

3.4 accept()

//接收请求,用于 TCP 网络程序中的 服务器

3.5 connect ()

//建立连接,用于 TCP 网络程序中的 服务器

四、sockaddr

1. 是什么?

        struct sockaddr(套接字地址结构体)是Linux用来保存套接字和套接字类型的结构体。


2. 为什么?

        使用Socket API要需要传入套接字,Linux选择用struct sockaddr保存套接字和套接字类型。在Linux下使用Socket API要传入struct  sockaddr*。


3. sockaddr的分类

        Linux中只设置了一套Socket API(套接字编程接口),但是有不同类型的套接字(用于IPv4的套接字、用于IPv6的、用于本地通信的) ,所以使用struct sockaddr、struct sockaddr_in 、struct  sockaddr_un来区分不同类型的套接字:


sockaddr、sockaddr_in 和 sockaddr_un结构体头部的16个比特位(2字节)都是一样的,这16位是地址类型用来区分套接字的类型的,根据套接字的类型(IPv4、IPv6……),分别定义为常数AF_INET、AF_INET6……


Socket API都用struct  sockaddr *类型传参,将 sockaddr_in 或 sockaddr_un强制类型转换为sockaddr,才能被Socket API识别。对于传进来的参数 sockaddr ,函数通过前两个字节,进行判断是网络通信还是本地通信,知道这个结果后再强制类型转换回  sockaddr_in 和 sockaddr_un结构体。这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数。


4.Linux中sockaddr的声明

  • struct  sockaddr(在头文件:<sys/socket.h>中


  • struct sockaddr_in (在头文件:<netinet/in.h>中)


  • struct sockaddr_un (在头文件:<sys/un.h>中)


5.创建并填充struct sockaddr_in

4.0 导入结构体定义所在的头文件。

#include <netinet/in.h>

struct sockaddr_in ,定义在头文件:<netinet/in.h>中


4.1 定义struct sockaddr_in变量。

struct sockaddr_in local;
  • struct sockaddr_in:用来定义Ipv4和Ipv6的套接字结构体,用于网络通信。
  • struct sockaddr_un :用来定义UNIX_Domain_Socket(Unix域套接字:用于同一台主机上进程间通信)。用于本地通信。

4.2 初始化结构体

bzero(&local, sizeof(local)); 

使用bzero() 或 memset()初始化结构体的内存空间为0 。


4.3 设置地址类型

local.sin_family = AF_INET;


4.4 设置端口号 (保存端口号的变量为:port,是一个2字节16位的整数)

local.sin_port = htons(port);

端口号要被对方获取,也是网络数据的一部分,所以要考虑大小端问题,使用htons函数将主机字节序转为网络字节序。


4.5 设置IP地址 (保存IP地址的变量为:ip,是一个点分十进制字符串)

local.sin_addr.s_addr = inet_addr(ip);

 inet_addr()的作用:

        1.将点分十进制字符串风格的IP地址 -> 4字节整数

        2.ip地址也要考虑大小端:将4字节整数 -> 网络序列


6.使用sockaddr传参

        Socket API只接受struct  sockaddr *类型传参,所以将 sockaddr_in、 sockaddr_un强制类型转换为sockaddr,才能被Socket API识别。
        对于传进来的参数 sockaddr ,函数通过前两个字节,进行判断是网络通信还是本地通信,知道这个结果后再强制类型转换回  sockaddr_in 和 sockaddr_un结构体。这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数。

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

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

相关文章

如何预防ssl中间人攻击?

当我们连上公共WiFi打开网页或邮箱时&#xff0c;殊不知此时可能有人正在监视着我们的各种网络活动。打开账户网页那一瞬间&#xff0c;不法分子可能已经盗取了我们的银行凭证、家庭住址、电子邮件和联系人信息&#xff0c;而这一切我们却毫不知情。这是一种网络上常见的“中间…

[保研/考研机试] KY3 约数的个数 清华大学复试上机题 C++实现

题目链接&#xff1a; KY3 约数的个数 https://www.nowcoder.com/share/jump/437195121691716950188 描述 输入n个整数,依次输出每个数的约数的个数 输入描述&#xff1a; 输入的第一行为N&#xff0c;即数组的个数(N<1000) 接下来的1行包括N个整数&#xff0c;其中每个…

wsl2安装mysql环境

安装完mysql后通过如下命令启动mysql service mysql start 会显示如下错误&#xff1a; mysql: unrecognized service 实际上上面显示的错误是由于mysql没有启动成功造成的 我们要想办法成功启动mysql才可以 1.通过如下操作就可以跳过密码直接进入mysql环境 2.如果想找到my…

nodejs+vue+elementui美食网站的设计与实现演示录像2023_0fh04

本次的毕业设计主要就是设计并开发一个美食网站软件。运用当前Google提供的nodejs 框架来实现对美食信息查询功能。当然使用的数据库是mysql。系统主要包括个人信息修改&#xff0c;对餐厅管理、用户管理、餐厅信息管理、菜系分类管理、美食信息管理、美食文化管理、系统管理、…

【百度翻译api】中文自动翻译为英文

欸&#xff0c;最近想做一些nlp的项目&#xff0c;做完了中文的想做做英文的&#xff0c;但是呢&#xff0c;国内爬虫爬取的肯定都是中文 &#xff0c;爬取外网的技术我没有尝试过&#xff0c;没有把握。所以我决定启用翻译&#xff0c;在这期间chatGPT给了我非常多的方法&…

关于电脑连接好WiFi却无法使用浏览器上网的一种解决方法

如果你的电脑的网络设置里选项是自动获取ip地址的话&#xff0c;那么大概率适用此方法。&#xff08;我这个已经是填好的&#xff0c;之前是自动获取&#xff09; 方法步骤&#xff1a;这里分两步 &#xff08;1&#xff09;首先确定无法使用浏览器上网的原因。&#xff08;比…

windows11连接上WiFi但是无法上网

电脑经常会出现网络等问题&#xff0c;win11在连接到WiFi&#xff0c;但是无法正常上网。进行网络诊断显示“该设备或资源&#xff08;Web代理&#xff09;未设置为接收端口7890”。借鉴过网络上许多方法都没有解决。可以尝试使用以下这种方式解决&#xff0c;本人亲测已解决。…

电脑显示wifi连接但是不能上网(dns无法连接)

网络问题 电脑显示wifi连接但是不能上网 1.使用手机等其它设备&#xff0c;连接同一个wifi&#xff0c;检查是否出现问题 如果其它设备也不能使用&#xff0c;则为网络本身的问题 如果不是&#xff0c;在继续检查电脑的问题 2.诊断问题 打开 “网络和Internet设置”找到下…

WIFI已连接,无法上网

wifi已经连接但显示无网络访问权限&#xff0c;查看IP&#xff0c;没有获取到IP。 解决方法&#xff1a; 1、在左下角Windows开始处打开【设置】界面 2、选择【更新和安全】 3、点击左侧窗格中的【恢复】。 4、点击【重置此电脑】下方的【开始】按钮。 5、删除所有内容 重置…

函数的模拟实现

题一&#xff1a; 模拟实现strncpy #include <stdio.h>void my_strncpy(char* arr2, char* arr1, size_t num){int i 0;for (i 0; i < num; i){*(arr2 i) *(arr1 i);}}int main(){char arr1[] "hello liangzai";char arr2[10] { 0 };//strncpy(ar…

家里WIFI连接上了但是无法上网的问题解决方案

今天下午回家&#xff0c;发现我家的WIFI网络连接上了&#xff0c;但是没有网络。草&#xff0c;我猜肯定又是隔壁小孩蹭我家WiFi了&#xff0c;于是我决定&#xff0c;是时候做个了断了。 一、重启路由器 刚开始连上了WiFi但是没网&#xff0c;这种时候可以选择 拔掉路由器 的…

win11系统连接上WiFi却无法上网怎么解决?

问题描述&#xff1a; 昨天更新了一下电脑系统&#xff0c;从win10家庭版更新到win11家庭版本&#xff0c;当天用的还是好好的&#xff0c;但是一夜之间&#xff0c;第二天打开电脑只能链接WiFi&#xff0c;但是不能上网&#xff0c;真的很令人纳闷。 原因分析&#xff1a; 1、…

网络wifi已连接显示不可上网的解决方法教程

为什么无线网络连接上却不能上网呢&#xff1f;明明无线WiFi正常连接&#xff0c;但是打开浏览器却上不了网&#xff0c;估计很多朋友的笔记本电脑遇到过这样的情况&#xff0c;造成这个问题的原因有很多&#xff0c;下面小编给大家分析一下原因以及解决的方法&#xff0c;大家…

【C++】C++异常

文章目录 1. C语言传统处理错误的方式2. C异常的概念3. 异常的使用3.1 异常的抛出和捕获3.2 异常的重新抛出3.3 异常安全3.4 异常规范 4. C标准库的异常体系5. 自定义的异常体系6. 异常的优缺点 1. C语言传统处理错误的方式 C语言传统的错误处理机制有两个&#xff1a; 终止程…

95后女孩穿旗袍走红,老手艺在淘宝迎来不一样的改变

在淘宝上有很多特色店铺&#xff0c;95后少女曾四斤喊出了“穿四斤&#xff0c;瘦10斤”的响亮口号&#xff0c;她在淘宝开设了一家“四斤自制”的少女旗袍店铺&#xff0c;全是30岁以下的年轻小姑娘在消费&#xff0c;“杨超越刚了穿了我们家旗袍录了拜年视频”&#xff0c;她…

员工福利?年轻女子穿着旗袍给程序员揉肩膀,这样真的合适吗

员工福利。有一个男子&#xff0c;他是一名程序员&#xff0c;上班的时候&#xff0c;在他身后站着一个女子&#xff0c;那个女子是专门为他服务的&#xff0c;这个福利让其他的同事羡慕不已。那个女子为什么专门为他服务&#xff1f;那个女子站在他的身后&#xff0c;给他按摩…

国潮迎春 百花旗放|2022东方丽人旗袍大赛暨国潮旗袍春晚华丽落幕

深圳商界讯&#xff1a;2021年12月4日&#xff0c;在深圳大鹏新区玫瑰庄园国际艺术中心&#xff0c;由深圳丽影文化主办&#xff0c;深圳前海卫视协办、深圳楚商国际俱乐部与商协汇总会、广州巽彩商贸、广东康尼蒂克等赞助的2022东方丽人旗袍大赛暨国潮旗袍春晚隆重举行。 本次…

Git 入门

一、版本控制 1.1 什么是版本控制 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。简单说就是用于管理多人协同开…

[保研/考研机试] KY35 最简真分数 北京大学复试上机题 C++实现

题目链接&#xff1a; 最简真分数https://www.nowcoder.com/share/jump/437195121691719749588 描述 给出n个正整数&#xff0c;任取两个数分别作为分子和分母组成最简真分数&#xff0c;编程求共有几个这样的组合。 输入描述&#xff1a; 每组包含n&#xff08;n<600&…