当前位置: 首页 > news >正文

《TCP/IP网络编程》阅读笔记--Socket类型及协议设置

目录

1--协议的定义

2--Socket的创建

2-1--协议族(Protocol Family)

2-2--Socket类型(Type)

3--Linux下实现TCP Socket

3-1--服务器端

3-2--客户端

3-3--编译运行

4--Windows下实现 TCP Socket

4-1--TCP服务端

4-2--TCP 客户端

4-3--编译运行


1--协议的定义

        协议是对话中使用的通信规则,拓展到计算机领域可整理为“计算机间对话必备通信规则”。简言之,协议就是为了完成数据交换而定好的约定

2--Socket的创建

#include <sys/socket.h>int socket(int domain, int type, int protocol); // 创建成功返回文件描述符,创建失败返回-1;
// domain 表示 socket 中使用的协议族(Protocol Family)信息;
// type 表示 socket 数据传输的类型信息;
// protocol 表示计算机间通信中使用的协议信息(TCP、UDP);

2-1--协议族(Protocol Family)

头文件 sys/socket.h 中声明的协议族

        ①:PF_INET 表示 IPv4 互联网协议族;

        ②:PF_INET6 表示 IPv6 互联网协议族;

        ③:PF_LOCAL 表示本地通信的 UNIX 协议族;

        ④:PF_PACKET 表示底层 Socket 的协议族

        ⑤:PF_IPX 表示 IPX Novell 协议族;

        Socket 实际采用的最终协议信息通过 socket 函数的第三个参数(protocol)传递的,在指定的协议族范围内通过第一个参数决定第三个参数;

2-2--Socket类型(Type)

        Socket 类型指的是 Socket 的数据传输方式,一般决定了协议族并不能同时决定数据传输方式,因为同一个协议族中可能存在多种数据传输方式

        以下说明两种常用的 Socket 类型:

面向连接的 Socket:SOCK_STREAM,特点如下:

        ① 传输过程中数据不会丢失;

        ② 按序传输数据;

        ③ 传输的数据不存在数据边界;

面向连接的 Socket 只能与另外一个同样特性的 Socket 进行连接;

一句话概括面向连接的 Socket :可靠的、按序传递的、基于字节面向连接的数据传输方式;

面向消息的 Socket:SOCK_DGRAM,特点如下:

        ① 强调快速传输而非传输顺序;

        ② 传输的数据可能丢失也可能销毁;

        ③ 传输的数据有数据边界,即意味着接收数据的次数应和传输次数相同;

        ④ 限制每次传输的数据大小;

一句话概括面向消息的 Socket :不可靠的、不按序传递的、以数据的高速传输为目的的 Socket;

        参数 PF_INET 指 IPv4 网络协议族,SOCK_STREAM 指面向连接的数据传输,满足以上两个条件的协议只有 IPPPOTO_TCP,即可通过以下方式创建 TCP Socket:

int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

        同理,SOCK_DGRAM 指面向消息的数据传输方式,满足条件的协议只有 IPPPOTO_UDP,即可通过以下方式创建 UDP Socket:

int udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

3--Linux下实现TCP Socket

3-1--服务器端

// gcc tcp_server.c -o tcp_server
// ./tcp_server 9190
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>void error_handling(char *message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char *argv[]){int serv_sock;int clnt_sock;struct sockaddr_in serv_addr;struct sockaddr_in clnt_addr;socklen_t clnt_addr_size;char message[] = "Hello World!";if(argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}serv_sock = socket(PF_INET, SOCK_STREAM, 0); // 调用 socket 函数创建socketif(serv_sock == -1){error_handling("socket() error");}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(atoi(argv[1]));// 调用 bind 函数分配 ip 地址和端口号if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1){error_handling("bind() error");}// 调用 listen 函数将 socket 转为可接收连接状态if(listen(serv_sock, 5) == -1){error_handling("listen() error");}clnt_addr_size = sizeof(clnt_addr);// 调用 accept 函数受理连接请求// 没有连接请求的情况下,不会有返回情况,直到有连接请求为止clnt_sock = accept(serv_sock, (struct sockaddr*) &clnt_addr, &clnt_addr_size);if(clnt_sock == -1){error_handling("accept() error");}// 调用 write 函数传输数据write(clnt_sock, message, sizeof(message));close(clnt_sock);close(serv_sock);return 0;}

3-2--客户端

// gcc tcp_client.c -o tcp_client
// ./tcp_client 127.0.0.1 9190
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>void error_handling(char *message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char *argv[]){int sock;struct sockaddr_in serv_addr;char message[30];int str_len;int idx = 0, read_len = 0;if(argc != 3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET, SOCK_STREAM, 0);if(sock == -1){error_handling("socket() error");}memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr(argv[1]);serv_addr.sin_port = htons(atoi(argv[2]));if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1){error_handling("connect() error!");}while(read_len = read(sock, &message[idx++], 1)){if(read_len == -1){error_handling("read() error!");}str_len += read_len;}printf("Message from server : %s \n", message);printf("Function read call count: %d \n", str_len);close(sock);return 0;
}

3-3--编译运行

# TCP服务端
gcc tcp_server.c -o tcp_server
./tcp_server 9190# TCP客户端
gcc tcp_client.c -o tcp_client
./tcp_client 127.0.0.1 9190

4--Windows下实现 TCP Socket

4-1--TCP服务端

// gcc tcp_server_win.c -o tcp_server_win -lwsock32
// tcp_server_win 9190
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>// 打印错误信息
void ErrorHandling(char* message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char* argv[]){WSADATA wsaData;SOCKET hServSock, hClntSock;SOCKADDR_IN servAddr, clntAddr;int szClntAddr;char message[] = "Hello World!";if(argc != 2){printf("Usage: %s <port>\n", argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){ // 初始化套接字库ErrorHandling("WSAStartup() error!");}hServSock = socket(PF_INET, SOCK_STREAM, 0); // 创捷socketif(hServSock == INVALID_SOCKET){ErrorHandling("socket() error!");}memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = htonl(INADDR_ANY);servAddr.sin_port = htons(atoi(argv[1])); // 端口if(bind(hServSock, (SOCKADDR*) &servAddr, sizeof(servAddr)) == SOCKET_ERROR){ // 给 socket 分配 ip 地址和端口号ErrorHandling("bind() error!");}if(listen(hServSock, 5) == SOCKET_ERROR){ // 置于listen状态,使socket可接收客户端连接请求ErrorHandling("listen() error!");}szClntAddr = sizeof(clntAddr);hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr); // 使socket受理客户端的连接请求if(hClntSock == INVALID_SOCKET){ErrorHandling("accept() error!");}send(hClntSock, message, sizeof(message), 0); // 向连接的客户端发送数据closesocket(hClntSock);closesocket(hServSock);WSACleanup(); // 注销初始化的套接字库return 0;
}

4-2--TCP 客户端

// gcc tcp_client_win.c -o tcp_client_win -lwsock32
// tcp_client_win 127.0.0.1 9190
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>// 打印错误信息
void ErrorHandling(char* message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char* argv[]){WSADATA wsaData;SOCKET hSocket;SOCKADDR_IN servAddr;char message[30];int strLen = 0;int idx = 0, readLen = 0;if(argc != 3){printf("Usage: %s <IP> <port>\n", argv[0]);exit(1);}if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){ // 初始化套接字库ErrorHandling("WSAStartup() error!"); }hSocket = socket(PF_INET, SOCK_STREAM, 0); // 创捷面向连接的 TCP Socketif(hSocket == INVALID_SOCKET){ErrorHandling("socket() error!");}memset(&servAddr, 0, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_addr.s_addr = inet_addr(argv[1]);servAddr.sin_port = htons(atoi(argv[2]));if(connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR){ // 向服务器端发送连接请求ErrorHandling("connect() error!");}while(readLen = recv(hSocket, &message[idx++], 1, 0)){ // 接收服务器发来的数据if(readLen == -1) ErrorHandling("read() error!");strLen += readLen;if(message[idx - 1] == '\0') break; // 读取到最后一个字节}printf("Message from server: %s \n", message); printf("Function read call count: %d \n", strLen);closesocket(hSocket);WSACleanup(); // 注销初始化的Winsock库return 0;
}

4-3--编译运行

# TCP服务端
gcc tcp_server_win.c -o tcp_server_win -lwsock32
tcp_server_win 9190# TCP客户端
gcc tcp_client_win.c -o tcp_client_win -lwsock32
tcp_client_win 127.0.0.1 9190

相关文章:

《TCP/IP网络编程》阅读笔记--Socket类型及协议设置

目录 1--协议的定义 2--Socket的创建 2-1--协议族&#xff08;Protocol Family&#xff09; 2-2--Socket类型&#xff08;Type&#xff09; 3--Linux下实现TCP Socket 3-1--服务器端 3-2--客户端 3-3--编译运行 4--Windows下实现 TCP Socket 4-1--TCP服务端 4-2--TC…...

GitHub使用教程

GitHub使用教程 视频教程一&#xff1a;Github 新手够用指南 | 全程演示&个人找项目技巧放送_哔哩哔哩_bilibili 笔记&#xff1a; README.md编写教程&#xff1a;Typora官方免费版与入门教程__阿伟_的博客-CSDN博客 找开源项目的一些途径 • https://github.com/trendin…...

sql server 分区表

分区表 分区表是在SQL Server 2005之后的版本引入的特性&#xff0c;这个特性允许把逻辑上的一个表在物理上分为很多部分。换句话说&#xff0c;分区表从物理上看是将一个大表分成几个小表&#xff0c;但是从逻辑上看&#xff0c;还是一个大表。 步骤 创建分表区的步骤分为…...

开源许可证概述:GNU, BSD, Apache, MPL, 和 MIT

前言 开源许可证是开源软件分发的基础。它们定义了使用者如何使用&#xff0c;修改&#xff0c;分发开源软件。在这篇文章中&#xff0c;我们将探讨五种常见的开源许可证&#xff1a;GNU通用公共许可证 (GNU GPL)&#xff0c;BSD许可证&#xff0c;Apache许可证&#xff0c;Mo…...

java中log使用总结

目录 一、概述1.1. 核心日志框架1.2 门面日志框架 二、最佳实践2.1 核心日志框架API包2.2 门面日志框架依赖2.3 集成使用2.3.1 集成jcl2.3.2 集成slf4j2.3.2.1 slf4j集成单一框架2.3.2.2 slf4j整合混合框架 三、总结3.1 所有相关包3.1.1 核心日志框架包3.1.2 门面日志框架3.1.3…...

【Java】传输层协议TCP

传输层协议TCP TCP报文格式首部长度保留位32位序列号和32位确认应答号标记ACKSYNFINRSTURGPSH 16位窗口大小16位校验和16位紧急指针选项 TCP特点可靠传输实现机制-确认应答超时重传连接管理机制三次握手四次挥手特殊情况 滑动窗口流量控制拥塞控制延迟应答捎带应答面向字节流粘…...

计算机网络基础知识(非常详细)

1. 网络模型 1.1 OSI 七层参考模型 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;参考模型&#xff0c;即开放式系统互联&#xff0c;是网络通信的标准模型。一般称为 OSI 参考模型或七层模型。 它是一个七层的、抽象的模型体&#xff…...

如何进行SEO优化数据分析?(掌握正确的数据分析方法,让您的网站更上一层楼!)

在互联网时代&#xff0c;SEO优化已经成为了每一个网站运营者必备的技能。而在SEO优化中&#xff0c;数据分析更是至关重要的一环。在本文中&#xff0c;我们将会详细介绍如何正确的进行SEO优化数据分析&#xff0c;让您的网站更上一层楼&#xff01; 数据分析的重要性 数据分…...

Golang不同平台编译的思考

GOOS和GOARCH $GOOS可选值如下&#xff1a; darwin dragonfly freebsd linux netbsd openbsd plan9 solaris windows $GOARCH可选值如下 386 amd64 arm 在编译的时候我们可以根据实际需要对这两个参数进行组合。更详细的说明可以进官网看看 ## http://golang.org/cmd/go http…...

SpringSecurity学习

1.认证 密码校验用户 密码加密存储 Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}} 我们没有这个配置&#xff0c;默认明文存储, {id}password;实现…...

时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测

时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测 目录 时序预测 | MATLAB实现ICEEMDAN-iMPA-BiLSTM时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 ICEEMDAN-iMPA-BiLSTM功率/风速预测 基于改进的自适应经验模态分解改进海洋捕食者算法双向长短期记忆…...

二叉树(上)

“路虽远&#xff0c;行则将至” ❤️主页&#xff1a;小赛毛 目录 1.树概念及结构 1.1树的概念 1.2 树的相关概念 1.3 树的表示&#xff08;树的存储&#xff09; 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树 2.3 特殊的二叉树&#xff1a; 2.4 二叉树的性质 3.二叉树的顺…...

Excel怎么批量生成文件夹

Excel怎么批量生成文件夹的链接: https://jingyan.baidu.com/article/ea24bc398d9dcb9b63b3312f.html...

c++ 学习之 静态成员变量和静态成员函数

文章目录 前言正文静态成员变量初始化操作如何理解共享一份数据访问权限 静态成员函数访问方式静态成员函数只能访问静态成员变量访问权限 前言 静态成员分为 1&#xff09;静态成员变量 所有对象共享一份数据在编译阶段分配空间类内声明&#xff0c;类外初始化 2&#xff09…...

C程序需要按下回车键才能读取字符

当编写涉及从终端输入字符的C程序时&#xff0c;有时会遇到需要按下回车键才能读取字符的问题。这是因为默认情况下&#xff0c;终端通常处于行缓冲模式&#xff0c;需要等待用户按下回车键才会将输入的字符发送给正在运行的程序。这可能会导致一些不便&#xff0c;尤其是当程序…...

x86体系结构(WinDbg学习笔记)

寄存器 eaxAccumulator累加器ebxBase register基寄存器ecxCounter register计数器寄存器edxData register - can be used for I/O port access and arithmetic functions数据寄存器-可用于I/O端口访问和算术函数esiSource index register源索引寄存器ediDestination index reg…...

Hadoop的第二个核心组件:MapReduce框架第四节

Hadoop的第二个核心组件&#xff1a;MapReduce框架 十、MapReduce的特殊应用场景1、使用MapReduce进行join操作2、使用MapReduce的计数器3、MapReduce做数据清洗 十一、MapReduce的工作流程&#xff1a;详细的工作流程第一步&#xff1a;提交MR作业资源第二步&#xff1a;运行M…...

算法通关村第十九关——最少硬币数

LeetCode322.给你一个整数数组 coins,表示不同面额的硬币&#xff0c;以及一个整数 amount&#xff0c;表示总金额。计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回-1。你可以认为每种硬币的数量是无限的。 示例1&…...

Linux ifconfig只显示 lo 网卡,没有ens网卡解决方案

项目场景&#xff1a; 虚拟机中linux无网络问题 问题描述 之前在调试linux的时候&#xff0c;由于一些不太清楚的误操作&#xff0c;导致ubuntu linux出现无网络问题&#xff0c;现象如下 ifconfig 只显示了 lo 网卡 lo 网卡&#xff1a;它是本地环回接口。 这意味着您的虚…...

Java复习-26-枚举

枚举&#xff08;替换多例设计&#xff09; 目的&#xff08;使用场景&#xff09; 不用也没啥 定义一个描述性别的类&#xff0c;那么该对象只有两个:男、 女。或者描述颜色基色的类&#xff0c;可以使用: 红色、绿色、蓝色。 功能 用于定义有限个数对象的一种结构&#x…...

别再只会用cv2.resize()了!手把手教你用Python复现最近邻和双线性插值(附完整代码)

从零实现图像缩放&#xff1a;深入理解最近邻与双线性插值的数学本质 当你在Jupyter Notebook里轻松敲下cv2.resize(img, (300,300))时&#xff0c;有没有想过这个看似简单的操作背后隐藏着怎样的数学魔法&#xff1f;今天我们将撕开OpenCV的封装外壳&#xff0c;用纯Python和N…...

3分钟搞定!Windows网络测速神器iperf3完整使用指南

3分钟搞定&#xff01;Windows网络测速神器iperf3完整使用指南 【免费下载链接】iperf3-win-builds iperf3 binaries for Windows. Benchmark your network limits. 项目地址: https://gitcode.com/gh_mirrors/ip/iperf3-win-builds 还在为网络速度不稳定而烦恼吗&#…...

从仿真卡死到波形完美:手把手调试Verilog Testbench时钟的那些坑

从仿真卡死到波形完美&#xff1a;手把手调试Verilog Testbench时钟的那些坑 数字电路仿真中&#xff0c;时钟信号就像交响乐团的指挥棒&#xff0c;一个微小的节奏错误就可能导致整个系统失序。刚接触Verilog仿真的工程师们&#xff0c;往往会在时钟生成这个看似简单的环节栽跟…...

别再折腾源码编译了!Ubuntu 20.04下用apt-get一键安装Asterisk PBX(附SIP账号配置详解)

别再折腾源码编译了&#xff01;Ubuntu 20.04下用apt-get一键安装Asterisk PBX&#xff08;附SIP账号配置详解&#xff09; 如果你正在寻找一种快速搭建企业级电话系统的方法&#xff0c;那么Asterisk PBX绝对值得考虑。作为开源PBX领域的标杆&#xff0c;Asterisk提供了完整的…...

FPGA LVDS输入作为模拟比较器的原理、设计与工程实践

1. 项目概述&#xff1a;当LVDS输入遇上模拟电压 最近几年&#xff0c;各大FPGA厂商都在力推自家的“模拟-数字转换器&#xff08;ADC&#xff09;IP核”&#xff0c;宣传其如何集成便利、性能优越。这让我这个老工程师不禁琢磨&#xff0c;这些IP核的底层原理究竟是什么&#…...

6自由度KUKA机械臂自主抓取系统:ROS架构设计与逆运动学技术实现深度解析

6自由度KUKA机械臂自主抓取系统&#xff1a;ROS架构设计与逆运动学技术实现深度解析 【免费下载链接】pick-place-robot Object picking and stowing with a 6-DOF KUKA Robot using ROS 项目地址: https://gitcode.com/gh_mirrors/pi/pick-place-robot 在工业自动化领…...

数字音频抖动抑制技术与DSS™同步方案解析

1. 数字音频系统中的抖动现象解析抖动&#xff08;Jitter&#xff09;是数字音频领域最令人头痛的问题之一&#xff0c;它就像一位不守时的乐队指挥——当每个音符的演奏时机出现微秒级的偏差时&#xff0c;整首乐曲就会失去原有的韵律和质感。在技术层面&#xff0c;抖动被定义…...

Claude Orchestra:基于Claude模型的AI智能体编排框架实战指南

1. 项目概述&#xff1a;Claude Orchestra 是什么&#xff0c;以及它为何值得关注最近在探索如何将大型语言模型&#xff08;LLM&#xff09;的能力更系统地整合到工作流中时&#xff0c;我遇到了一个名为mianham9042/claude-orchestra的项目。这个名字本身就很有意思——“Cla…...

AI编程助手色彩科学技能库:从OKLCH到APCA的现代色彩实践

1. 项目概述&#xff1a;一个为AI编程助手打造的“色彩科学专家”技能库如果你和我一样&#xff0c;经常在开发与色彩相关的工具、设计系统&#xff0c;或者需要向团队解释为什么某个颜色方案行不通时&#xff0c;总得反复查阅同一堆资料——那个讲解OKLAB色彩空间的视频、那篇…...

AI时代开发者必备:生成式AI应用与核心工程能力双螺旋进阶

1. 项目概述&#xff1a;当AI成为你的新同事最近和几个带团队的朋友聊天&#xff0c;发现一个挺有意思的现象&#xff1a;团队里那些能熟练把AI工具“用起来”的开发者&#xff0c;和那些还在“观望”甚至“抵触”的开发者&#xff0c;在项目交付效率、问题解决深度上&#xff…...