Linux —— 网络编程套接字

目录

一,网络字节序

二,socket编程接口

sockaddr结构


源IP地址、目的IP地址,在IP数据包头部,有此两个IP地址;

端口号,是传输层协议的内容;

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程,告诉操作系统当前数据要交给哪个进程来处理;
  • IP地址+端口号能标识网络上的某台主机的某个进程;
  • 一个端口号只能被一个进程占用;

一个进程可以绑定多个端口号,但一个端口号不能被多个进程绑定;

源端口号、目的端口号,传输层协议(TCP、UDP)的数据段中有此两个端口号,描述“数据是谁发的,要发给谁”;

TCP协议(Transmission Control Protocol 传输控制协议)

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

UDP协议(User Datagram Protocol 用户数据报协议)

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

一,网络字节序

        内存中的多字节数据相当于内存地址有大小端之分,磁盘文件中的多字节数据相当于文件中的偏移也有大小端之分,网络数据流同样也有大小端之分;

如何定义网络数据流的地址:

  • 发送主机通常将发送缓冲区中的数据按内存从低到高的顺序发送;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此网络数据流的地址,先发出的数据是低地址,后发出的数据是高地址;
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节;
  • 不管这台主机是大端机还是小段机,都会按照TCP/IP协议规定的网络字节序来发送、接收数据;
  • 如当前发送主机是小段,需先将数据转成大端,否则忽略直接发送即可;

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

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
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表示32位长整数从主机字节序转换为网络字节序;
  • 如主机是小端字节序,这些函数将参数做相应的大小端转换,然后返回;
  • 如主机是大端字节序,这些函数不做转换,然后返回;

二,socket编程接口

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 sockid, const struct sockaddr* addr, socklen_t addlen);

sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,及UNIX Domain Socket;然而各种网络协议的地址格式并不相同;

  • IPv4、IPv6地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32位IP地址;
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET16;这样,只要取得某种sockadddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容;
  • socket API可以都用struct sockaddr*类型表示,在使用的时候需要强制转化sockaddr_in;这样的好处是程序的通用性,可以接收IPv4、IPv6,及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;

//socketaddr 结构
struct sockaddr{
    __SOCKADDR_COMMON (sa_);
    char sa_data[14];
};
//sockadddr_in 结构
struct sockaddr_in{
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;
    struct in_addr_ sin_addr;

    unsigned char sin_zero[sizeof (struct sockaddr) -
        __SOCKADDR_COMMON_SIZE - 
        sizeof (in_port_t) -
        sizeof (struct in_addr)];
};

虽然socket API的接口是sockaddr,但是真正在基于IPv4编程时,使用的数据结构是sockaddr_in;这个结构里主要有三部分信息:地址类型、端口号、IP地址;

//in_addr 结构
typedef uint32_t in_addr_t;
struct in_addr{
    in_addr_t s_addr;
};

in_addr用来表示一个IPv4的IP地址,其实就是一个32位的整数;

//UDP server.cc
#include <iostream>    
#include <cstring>    
#include <unistd.h>    
#include <sys/types.h>    
#include <sys/socket.h>    
#include <netinet/in.h>    
    
#define PORT 8081    
    
int main()    
{    
    int sock = socket(AF_INET, SOCK_DGRAM, 0);    
    if(sock < 0){    
        std::cerr << "socket error" << std::endl;    
        return 1;    
    }    
    std::cout << "sock: " << sock << std::endl;    
    
    struct sockaddr_in local;    
    memset(&local, 0, sizeof(local));    
    local.sin_family = AF_INET;    
    local.sin_port = htons(PORT); //    
    local.sin_addr.s_addr = htonl(INADDR_ANY);    
    
    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0){    
      std::cout << "bind error " << std::endl;    
      return 1;    
    }    
    
    char message[1024];    
    for(; ;){    
      struct sockaddr_in peer;    
      socklen_t len = sizeof(peer);    
      ssize_t s = recvfrom(sock, message, sizeof(message)-1, 0, (struct sockaddr*)&peer, &len);    
      if(s > 0){    
        message[s] = '\0';    
        std::cout << "client# " << message << std::endl;    
        sendto(sock, message, strlen(message), 0, (struct sockaddr*)&peer, len);                                                               
      }    
      else{ 
        //todo
      }    
    }    
    
    close(sock);    
    return 0;    
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是Amazon Simple Email Service(SES 群发邮件)

Amazon Simple Email Service&#xff08;Amazon SES&#xff09;让您可以使用 Amazon SES API 或 SMTP 接口放心地联络到客户&#xff0c;而无需使用本地简单邮件传输协议&#xff08;Simple Mail Transfer Protocol&#xff0c;SMTP&#xff09;电子邮件服务器。 目录 什么是…

C++学习---信号处理机制、中断、异步环境

文章目录 前言信号处理signal()函数关于异步环境 信号处理函数示例raise()函数 前言 信号处理 关于信号&#xff0c;信号是一种进程间通信的机制&#xff0c;用于在程序执行过程中通知进程发生了一些事件。在Unix和类Unix系统中&#xff0c;信号是一种异步通知机制&#xff0c…

代码随想录 Day43 动态规划11 LeetCode T309 买卖股票的最佳时期含冷冻期 T714买卖股票的最佳时机含手续费

LeetCode T309 买卖股票的最佳时机含冷冻期 题目链接:309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这题其实就是将卖出的状态拆分成三个状态 1.前两天就卖出并一直保持卖出的状态 2.今天卖出的状态 3.今天是冷冻期的状态 当然还有一个…

最新支付宝转卡码生成之转账源代码(隐藏部分卡号)

一、需要准备好自己的卡号、名称、以及对应的姓名 二、然后将自己的信息填入下面的代码中 三、然后将拼接好的代码&#xff0c;利用转码技术生产对应的二维码 四、这样一个跳转银行卡二维码的转账码就做好了 效果演示&#xff1a;如下 支付宝扫码、跳转码、转卡码、隐藏卡号…

【刷题】力扣每日一题 : 381、2300、765

前言 本篇文章用于记录在做力扣每日一题的时候遇到的一些知识点以及自己的思路 381 题干 题目链接 我的思路及做题过程 思路1 我的想法是 记录每个字符串的字母出现个数 然后比较两个字符串是否有字母同时出现 class Solution { public:int judge(string s1, string s2…

asp.net core自定义异常过滤器并记录到Log4Net日志

1.创建异常过滤器特性 using Log4Net.Controllers; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters;namespace Log4NetTest {public class CustomerExceptionFilterAttribute : Attribute, IExceptionFilter{private readonly ILogger<CustomerE…

CSS布局001:画各种三角形

CSS实战中&#xff0c;有很多时候采用css来绘制三角形&#xff0c;而不是采用图片的方式&#xff0c;这样有利于快速成型&#xff0c;不用多调用服务器数据。 CSS代码 上三角 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid…

idea配置tomcat参数,防止nvarchar保存韩文、俄文、日文等乱码

描述下我的场景&#xff1a; 数据库服务器在远程机器上&#xff0c;数据库使用的Oracle&#xff0c;字符集是ZHS16GBK&#xff0c;但保存韩文、俄文、日文等字段A的数据类型是nvarchar(120)&#xff0c;而nvarchar使用的是Unicode 编码&#xff0c;有点乱。。 遇到的问题&…

ArcGIS:如何迭代Shp文件所有要素并分别导出为Shp文件?

01 前言 尝试用IDL实现&#xff0c;奈何又涉及新的类IDLffShape&#xff0c;觉得实在没有必要学习的必要&#xff0c;毕竟不是搞开发&#xff0c;只是做做数据处理&#xff0c;没必要拿IDL不擅长的且底层的东西自己造轮子。 这里想到使用Python去解决&#xff0c;gdal太久没用…

微信的聊天记录导出到网页中的最快方法,语音能听,图片视频能看

12-7 如果你有把微信的聊天记录导出到表格或者网页上的需求&#xff0c;适合看看本文章&#xff0c;本文的方法可以让你把微信的聊天记录导出备份&#xff0c;可以在完全脱离微信的情况下随时调取查看聊天数据。 本文介绍的软件可以导出两种格式的聊天记录备份文件&#xff0…

【C语言】冒泡排序(图解)

&#x1f308;write in front :&#x1f50d;个人主页 &#xff1a; 啊森要自信的主页 &#x1f308;作者寄语 &#x1f308;&#xff1a; 小菜鸟的力量不在于它的体型&#xff0c;而在于它内心的勇气和无限的潜能&#xff0c;只要你有决心&#xff0c;就没有什么事情是不可能的…

wsl [Ubuntu20.04.6] 安装 Hadoop

文章目录 1.安装WSL2.安装Java安装Hadoop3.3配置文件1.修改hadoop-env.sh2.修改core-site.xml3.修改hdfs-site.xml ssh启动 1.安装WSL 重启电脑 管理员打开powershell PS C:\windows\system32> wsl --list --online PS C:\windows\system32> wsl --install -d Ubuntu-2…

OpenCV图像坐标系

绘制代码: X轴 # 选取两个点 point1 = (20, 0) point2 = (200, 0)# 在图像上绘制连接线 cv2.line(img, point1, point2, (

NSSCTF-Crypto入门题 练习记录贴 ‘‘一‘‘

文章目录 前言001[鹤城杯 2021]easy_crypto002[强网拟态 2021]拟态签到题003[SWPUCTF 2021 新生赛]crypto8004[SWPUCTF 2021 新生赛]crypto7005[SWPUCTF 2021 新生赛]crypto6006[SWPUCTF 2021 新生赛]ez_caesar007[SWPUCTF 2021 新生赛]crypto10008[鹤城杯 2021]A_CRYPTO009[SW…

Spring -Spring之循环依赖源码解析

什么是循环依赖&#xff1f; 很简单&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象。 比如&#xff1a; // A依赖了B class A{public B b; }// B依赖了A class B{public A a; }那么循环依赖是个问题吗&#xff1f; 如果不考虑Spring&#xff0c;循环依赖并…

SparkSQL语法优化

SparkSQL在整个执行计划处理的过程中&#xff0c;使用了Catalyst 优化器。 1 基于RBO的优化 在Spark 3.0 版本中&#xff0c;Catalyst 总共有 81 条优化规则&#xff08;Rules&#xff09;&#xff0c;分成 27 组&#xff08;Batches&#xff09;&#xff0c;其中有些规则会被归…

junit写搜索树测试

用法 assertTrue(range.contains("Two")); 2个参数,右边错就打印左边. AbstractSelfBalancingBinarySearchTree abt; AbstractBinarySearchTree.Node node; Before public void setUp() { abt new AbstractSelfBalancingBinarySearchTree() { Override protecte…

【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(引导篇)

深入挖掘和分析如何提升服务的性能以及执行效率 前提介绍知识要点 性能概述教你看懂程序的性能案例介绍性能指标性能的参考指标性能瓶颈&#xff08;木桶原理&#xff09; 性能分析三大定律Amdahl定律计算公式参数解释案例分析定律总结 Gustafson定律与Amdahl定律相对立Gustafs…

Panda3d 场景管理

Panda3d 场景管理 文章目录 Panda3d 场景管理有关分层场景图的重要信息NodePathNodePath 以及 Node 的函数调用模型文件文件格式加载模型文件将模型放置在场景图中模型缓存压缩模型异步加载模型通过回调函数进行 常见的状态变化修改节点的位置和姿态改变父级节点改变颜色隐藏和…

【多线程 - 01、概述】

进程 几乎所有的操作系统都支持进程概念&#xff0c;进程是处于运行过程中的程序&#xff0c;进程是操作系统中进行资源分配的基本单位。 三个基本特征 独立性&#xff1a;指进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。而对于未建立任何进程的程序&…