09.计算机网络——套接字编程

这篇具有很好参考价值的文章主要介绍了09.计算机网络——套接字编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


网络字节序

​ 内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分。
​ TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据。为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

09.计算机网络——套接字编程,计算机网络,Linux,计算机网络,socket,tcp,udp

  • h表示host,n表示network,l表示32位长整数,s表示16位短整数。

  • htonl表示将32位的长整数从主机字节序转换为网络字节序。

  • ntohl表示将32位的长整数从网络字节序转换为主机字节序。


socket编程

​ socket套接字通常指的是封装了ip和port的结构体,其是网络编程中的一种通信机制,支持TCP/IP的网络通信的基本操作单元,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。


socket 常见API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);

// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);

// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);

// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);

// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

sockaddr结构

09.计算机网络——套接字编程,计算机网络,Linux,计算机网络,socket,tcp,udp

套接字分类:

  1. 域间套接字 —— 本地通信
  2. 原始套接字 —— 允许绕过传输层,直接跟底层打交道,主要用来写一些工具。
  3. 网络套接字 —— 网络通信

​ 理论上是三种应用场景,对应的应该是三套接口,但是Linux设计套接字的时候不想设计过多的接口,所以Linux将所有的接口进行了统一,只使用sockaddr结构体来描述这三种场景。 但是真正在基于IPv4编程时, 使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息: 地址类型, 端口号, IP地址。

09.计算机网络——套接字编程,计算机网络,Linux,计算机网络,socket,tcp,udp


UDP编程

创建socket

#include <sys/types.h>
#include <sys/socket.h>
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
//参数
domain:指定网络层的协议
    AF_INT: 使用ipv4版本的ip协议
    AF_INT6:使用ipv6版本的ip协议
    AF_UNIX:本地通信
type: 指定套接字的类型
    SOCK_DGRAM :使用UDP数据报套接字
	SOCK_STREAM:使用TCP字节流套接字
protocol:指定使用的协议
      0:使用套接字类型对应的默认协议

绑定socket

int bind(int socket, const struct sockaddr* address,socklen_t address_len);*
//参数
sockfd:		socket函数返回的套接字描述符
addr:		地址信息结构体成员,struct sockaddr 是一个通用地址信息结构
address_len:地址信息结构的长度

sendto发送数据

ssize_t sendto(int sockfd, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen);
//参数
sockfd: 	套接字描述符
buf:		要发送的数据
len:		发送数据的长度
flags:		0-阻塞发送
dest_addr:	 目标主机的地址信息结构体
addrlen:	目标主机地址信息结构体的长度
//返回值
成功返回发送的字节数量,失败返回-1

recvform接收数据

ssize_t recvfrom(int sockfd, void* buf, size_t len, int flags,struct sockaddr* src_addr, socklen_t* addrlen);
//参数
sockfd:		套接字描述符
buf:		将数据接收到buf当中
len:		buf的最大接收能力
flags:		0-阻塞接收
src_addr:	数据来源的主机地址信息结构体  
addrlen:	输入输出型参数
//返回值
成功则返回实际接收到的字符数,失败返回-1,错误原因会存于errno中

关闭socket

close(int sockfd);
//sockfd:		套接字描述符

TCP编程

创建socket

#include <sys/types.h>
#include <sys/socket.h>
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
//参数
domain:指定网络层的协议
    AF_INT: 使用ipv4版本的ip协议
    AF_INT6:使用ipv6版本的ip协议
    AF_UNIX:本地通信
type: 指定套接字的类型
    SOCK_DGRAM :使用UDP数据报套接字
	SOCK_STREAM:使用TCP字节流套接字
protocol:指定使用的协议
      0:使用套接字类型对应的默认协议
//返回值:
socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,程序可以像读写文件一样用read/write在网络上收发数据;调用出错则返回-1

绑定socket

int bind(int socket, const struct sockaddr* address,socklen_t address_len);*
//参数
sockfd:		socket函数返回的套接字描述符
addr:		地址信息结构体成员,struct sockaddr 是一个通用地址信息结构
address_len:地址信息结构的长度

listen监听套接字

//listen()声明sockfd处于监听状态
int listen(int sockfd, int backlog);
//参数
sockfd:	套接字描述符
backlog:已完成连接队列的大小
//返回值:
  成功:0
  失败:-1

当客户端和服务端进行三次握手的时候会存在两种状态:连接还未建立和连接已建立,此时操作系统内核中就会存在两个队列:未完成连接队列和已完成连接队列。当完成三次握手后会由未完成连接队列放到已完成连接队列,而backlog就是已完成连接队列的大小,backlog影响了服务端并发接收连接的能力。

accept服务端接收连接套接字

//从已经完成连接队列中获取已经完成三次握手的连接,没有连接时,调用accept会阻塞等待。
int accept(int sockfd, struct sockaddr* addr, socklen_t * addrlen);
//参数
sockfd:套接字描述符(listen_sockfd)
addr:输出型参数,保存客户端地址信息结构(客户端IP,客户端的端口)
addrlen:输入输出参数,传入缓冲区的大小,传出客户端地址信息结构的长度
//返回值
  成功:返回新连接的套接字描述符
  失败:返回-1

三次握手的时候是对listen_sockfd进行操作,当调用accept()会在Tcp服务端内部创建一个新的套接字new_sockfd,三次握手之后的数据收发都是多new_sockfd进行操作。


connect客户端连接套接字

//客户端需要调用connect()连接服务器
int connect(int sockfd, const struct sockaddr * addr,socklen_t addrlen);
//参数
sockfd:套接字描述符(listen_sockfd)
addr:服务端地址信息结构(服务端IP,服务端的端口)
addrlen:服务端地址信息结构的长度
//返回值
  成功:返回0
  小于0,连接失败

send发送数据

ssize_t send(int sockfd, const void * buf, size_t len, int flags);

//参数
sockfd:套接字描述符(new_sockfd)
buf:待要发送的数据
len:发送数据的长度
flags:
  0:阻塞发送
  MSG_OOB:发送带外数据,在紧急情况下所产生的数据,会越过前面进行排队的数据优先进行发送。
    
//返回值
  大于0:返回发送的字节数量
  -1:发送失败

recv接收数据

ssize_t recv(int sockfd, void * buf, size_t len, int flags);

//参数
sockfd:套接字描述符(new_sockfd)
buf:将接收的数据放到buf
len:buf的最大接收能力
flags:0:阻塞发送;如果客户端没有发送数据,调用recv会阻塞
    
//返回值
  大于0:正常接收了多少字节数据
  等于0:对端将连接关闭了
  小于0:接受失败

关闭socket

close(int sockfd);
//sockfd:		套接字描述符

工具

netstat

netstat -anp | grep [端口号]
  • 查看端口的使用情况

telnet

  • 进入cmd,使用telnet模仿TCP三次握手建立连接,在cmd窗口输入 “tenlet + 公网IP + 端口号” 即可模拟测试

地址转换函数

sockaddr_in中的成员struct in_addr sin_addr表示32位 的IP 地址,但是我们通常用点分十进制的字符串表示IP 地址,以下函数可以在字符串表示 和in_addr表示之间转换

字符串转in_addr的函数:

09.计算机网络——套接字编程,计算机网络,Linux,计算机网络,socket,tcp,udp

in_addr转字符串的函数:

09.计算机网络——套接字编程,计算机网络,Linux,计算机网络,socket,tcp,udp

inet_ntoa函数把这个返回结果放到了静态存储区,这个时候不需要我们手动进行释放。

socket编程注意细节

  • 客户端没有必要调用bind()固定一个端口号,否则如果在同一台机器上启动多个客户端,就会出现端口号被占用导致不能正确建立连接。
  • 服务器也不是必须调用bind(),但如果服务器不调用bind(), 内核会自动给服务器分配监听端口, 每次启动服务器时端口号都不一样,客户端要连接服务器就会遇到麻烦。
  • 多进程的客户端代码和单进程是一样的,父进程负责accept,子进程负责数据的接收和发送,若子进程一直不退出,则父进程一直在等待,永远无法接收新连接,可以使用自定义信号处理方式将SIGCHLD信号重新定义,当子进程退出发出SIGCHLD信号时,父进程则对子进程的资源进行回收。
  • 建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使用,也可以使用read和 write函数进行读写

代码案例

UDP案例

UDP · 程序员Jared/Linux - 码云 - 开源中国 (gitee.com)

TCP案例

TCP · 程序员Jared/Linux - 码云 - 开源中国 (gitee.com)文章来源地址https://www.toymoban.com/news/detail-601212.html

到了这里,关于09.计算机网络——套接字编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机网络---网络编程套接字(一)

    ✨ 计算机网络—网络编程套接字之UDP数据报套接字编程 作者介绍: 🎓作者:偷偷敲代码的青花瓷🐱‍🚀 👀作者的Gitee:代码仓库 📌系列文章推荐:计算机网络 ——网络原理之初识 ✨✨我和大家一样都是热爱编程✨,很高兴能在此和大家分享知识,希望在分享知识的同时,能和大

    2023年04月09日
    浏览(28)
  • 【计算机网络】网络编程套接字(一)

    目录 1.预备知识 1.1.理解源IP地址和目的IP地址 1.2.认识端口号 1.2.1.理解\\\"端口号\\\"和\\\"进程ID\\\" 1.2.2.理解源端口号和目的端口号 1.3.认识TCP/UDP协议 1.3.1.TCP协议 1.3.2.UDP协议 1.4.网络字节序 网络字节序和主机字节序的转换 2.socket编程接口 2.1.sockaddr结构 struct sockaddr_in 的具体结构: 2.

    2024年02月08日
    浏览(37)
  • 计算机网络 | socket IPC(本地套接字domain)

    欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。 专栏:《Linux从小白到大神》《网络编程》 soc

    2024年02月08日
    浏览(31)
  • 【计算机网络】网络编程套接字&UDP服务器客户端的简单模拟

    需要云服务器等云产品来学习Linux的同学可以移步/–腾讯云–/官网,轻量型云服务器低至112元/年,优惠多多。(联系我有折扣哦) 每台主机都有自己的IP地址,当数据在进行通信的时候,除了要发送的数据外,在报头里面还要包含发送方的IP和接收方的IP,这里发送方的IP就

    2024年02月20日
    浏览(39)
  • 计算机网络套接字编程实验-TCP多进程并发服务器程序与单进程客户端程序(简单回声)

    1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解多进程(Multiprocess)相关基本概念,理解父子进程之间的关系与差异,熟练掌握基于fork()的多进程编程模式; ·理解僵尸进程产生原理,能基于|sigaction()或signal(),使用waitpid()规避僵尸进程产生; ·

    2024年02月12日
    浏览(34)
  • 计算机网络套接字编程实验-TCP单进程循环服务器程序与单进程客户端程序(简单回声)

    1.实验系列 ·Linux NAP-Linux网络应用编程系列 2.实验目的 ·理解并掌握在程序运行时从命令行读取数据的C语言编程方法; ·理解并掌握基于命令参数设置并获取IP与Port的C语言编程方法; ·理解并掌握套接字地址的数据结构定义与地址转换函数应用; ·理解并掌握网络字节序

    2024年02月11日
    浏览(78)
  • 网络编程套接字 | UDP套接字

    前面的文章中我们叙述了网络编程套接字的一些预备知识点,从本文开始我们就将开始UDP套接字的编写。本文中的服务端与客户端都是在阿里云的云服务器进行编写与测试的。 在v1的版本中我们先来使用一下前面讲过得一些接口,简单的构建一个udp服务器: 然后运行上述的程

    2024年02月09日
    浏览(38)
  • 【JaveEE】网络编程之TCP套接字、UDP套接字

    目录 1.网络编程的基本概念 1.1为什么需要网络编程  1.2服务端与用户端 1.3网络编程五元组  1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点  2.2UDP套接字API 2.2.1DatagramSocket类 2.2.2DatagramPacket类  2.2.3基于UDP的回显程序 2.2.4基于UDP的单词查询  3.TCP套接字编程 3.1TCP套接字的特

    2023年04月13日
    浏览(46)
  • 【JavaEE】网络编程之TCP套接字、UDP套接字

    目录 1.网络编程的基本概念 1.1为什么需要网络编程  1.2服务端与用户端 1.3网络编程五元组  1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点  2.2UDP套接字API 2.2.1DatagramSocket类 2.2.2DatagramPacket类  2.2.3基于UDP的回显程序 2.2.4基于UDP的单词查询  3.TCP套接字编程 3.1TCP套接字的特

    2023年04月20日
    浏览(47)
  • 网络编程套接字(3)——Java数据报套接字(UDP协议)

    目录 一、Java数据报套接字通信模型 二、UDP数据报套接字编程 1、DatagramSocket         (1)DatagramSocket构造方法         (2)DatagramSocket方法 2、DatagramPacket         (1)DatagramPacket构造方法         (2)DatagramPacket方法 3、InetSocketAddress 三、代码示例:回显服务

    2024年03月12日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包