linux网络编程基础-socket

article/2025/9/11 9:18:31

Socket基础以及相关应用函数

什么是socket

socket,也就是我们所谓的套接字,就像插座一样。

IP地址可以在网络环境中唯一的标识一台主机

端口号:在主机当中唯一标识一个进程。

因此,IP地址+端口号,就可以在网络环境中唯一标识一个进程,而在网络环境中被唯一标识的这个进程,就是socket。

套接字的通讯原理示意图
再说这个套接字,它本质上是Linux操作系统当中文件的一种类型。确切而言,它是一种伪文件,不占用存储。

再说,linux中实际占用存储空间的文件类型有三种:

  • 普通文件
  • 目录
  • 软连接,内部记录所指向文件的文件的路径名。

除此之外,还有四种文件:

  • 字符设备
  • 块设备
  • 管道
  • 套接字

说到管道,它有一个读段和一个写端。而对应到管道,我们来分析socket,这个socket也会建立一个文件描述符,而它的特别之处在于,它有两个缓冲区:一个负责读入,一个负责写出。因此,socket是全双工双向通信的。

从上面的通讯原理示意,可知道套接字都是成对出现的。

相关的应用函数

IP地址转换函数

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

Sockaddr数据结构:

struct sockaddr {sa_family_t sa_family;      /*address family, AF_xxx */char sa_data[14];           /*14 bytes of protocol address */
};

Pv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位端口号和32位IP地址,IPv6地址用sockaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。

socket函数

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>int socket(int domain,int type, int protocol);

domain:

  • AF_INET, 这式大多数用来产生socket的协议,使用TCP或者UDP来传输,使用IPv4地址。

  • AF_INET6,类似,使用IPV6协议

  • AF_UNIT,本地协议,使用在Unix或者Linux上,一般式服务器与客户端在同一机器上时候使用

type也就是使用的协议类型:

  • 流式协议,默认方式tcp,SOCK_STREAM,这个协议是按照顺序的、可靠的、数据完整的
  • 报式协议,默认方式udp,SOCK_DGRAM,这个协议是无连接的,固定长度的传输。

protocal: 传0表示使用默认协议。

bind函数

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd,文件描述符;

addr,构建出IP地址加端口号

addrlen,sizeof(addr)

返回值,成功0,失败为-1,errno

**服务器程序所监听的网络地址和端口号通常是固定不变的,**客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号。

因此,bind的作用是将sockfd和addr绑定到仪器,使sockfd这个用于网络通讯的文件描述符监听addr所描述的地址和端口号。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8keZSPrU-1578983102870)(image.png)]

listen函数

listen声明sockfd处于监听状态,并指明同时最多能与我建立连接的客户端数量。

Accept函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2PgDx6GH-1578983102871)(image.png)]

以下程序,客户端连接服务器端,客户端输入字符串,服务器端将其转换为大写字符,然后客户端读入显示转换之后的字符串。在server中,有两层的while循环,第一层实现端口连接的监听,结合子线程的使用,在子线程中执行服务器的服务任务。

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
const int MAXLINE  = 80;
const int SERV_PORT=  6666;
const char serv_addr[] = "127.0.0.1";
int main(int argc, char *argv[])
{struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd, n, len;
sockfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, serv_addr, &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
while (1) {/_从标准输入获取数据_/printf("Now please input string: \n");fgets(buf, sizeof(buf), stdin);/_将数据写给服务器_/write(sockfd, buf, strlen(buf));       //写个服务器/_从服务器读回转换后数据_/len = read(sockfd, buf, sizeof(buf));printf("The data from server: \n");/_写至标准输出_/write(STDOUT_FILENO, buf, len);
}
close(sockfd);
return 0;}

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#define MAXLINE 80
#define SERV_PORT 6666
int main(void)
{
int sfd, conn_fd;
pid_t  pid;
int len, i,ret;
char buf[BUFSIZ], clie_IP[BUFSIZ];struct sockaddr_in serv_addr, clie_addr;
socklen_t clie_addr_len;/_创建一个socket 指定IPv4协议族 TCP协议_/
sfd = socket(AF_INET, SOCK_STREAM, 0);/_初始化一个地址结构 man 7 ip 查看对应信息_/
bzero(&serv_addr, sizeof(serv_addr));           //将整个结构体清零
serv_addr.sin_family = AF_INET;                 //选择协议族为IPv4
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //监听本地所有IP地址
serv_addr.sin_port = htons(SERV_PORT);          //绑定端口号    /_绑定服务器地址结构_/
bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));/_设定链接上限,注意此处不阻塞_/
listen(sfd, 64);                                //同一时刻允许向服务器发起链接请求的数量printf("wait for client connect ...\n");/_获取客户端地址结构大小_/ 
clie_addr_len = sizeof(clie_addr_len);
/_参数1是sfd;2传出参数,3传入传入参数, 全部是client端的参数_/printf("client IP:%s\tport:%d\n", 
inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), 
ntohs(clie_addr.sin_port));while (1)
{conn_fd = accept(sfd, (struct sockaddr _)&clie_addr, &clie_addr_len); /_监听客户端链接, 会阻塞*/if(conn_fd < 0){perror("accept: ");}printf("accept a new client, ip: %s\n", inet_ntoa(clie_addr.sin_addr));if((pid = fork()) == 0)                         //创建子进程处理刚刚接收的连接请求{while (1){/_读取客户端发送数据_/len = read(conn_fd, buf, sizeof(buf));write(STDOUT_FILENO, buf, len);/_处理客户端数据_/for (i = 0; i < len; i++)buf[i] = toupper(buf[i]);/_处理完数据回写给客户端_/write(conn_fd, buf, len); }close(sfd);exit(0);                                    //结束子进程            }else{close(conn_fd);                             //父进程关闭刚刚接收的连接请求,执行accept等待其他连接请求}
}
/_关闭链接_/
close(sfd);
close(conn_fd);
return 0;}

http://chatgpt.dhexx.cn/article/wGqsqfMn.shtml

相关文章

全双工管道

Fork() 函数&#xff1a; 返回0时是子进程&#xff0c;否则&#xff0c;是父进程。 pipe函数 int pipe(int filedes[2]); 返回值&#xff1a;成功&#xff0c;返回0&#xff0c;否则返回-1。参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道&#xff0c;fd[1]:写管道…

TCP/UDP 协议,和 HTTP、FTP、SMTP,区别及应用场景(单工,半双工,全双工)

TCP/UDP 协议&#xff0c;和 HTTP、FTP、SMTP&#xff0c;区别及应用场景 一、OSI 模型 OSI 模型主要作为一个通用模型来做理论分析&#xff0c;而TCP/IP 协议模型是互联网的实际通讯协议&#xff0c;两者一般做映射分析&#xff0c;以下不做严格区分和声明&#xff08;好吧&…

串口通讯理解

机器的通信方式有两种&#xff0c;分别是并行通信与串行通信 并行通信&#xff1a;并行通信是指多比特数据同时通过并行线进行传送&#xff0c;这样数据传送速度大大提高&#xff0c;但并行传送的线路长度受到限制&#xff0c;因为长度增加&#xff0c;干扰就会增加&#xff0c…

Linux-C语言-利用有名管道简单实现两个进程间的全双工通信

有名管道特点: 1.有名管道是对无名管道的改进&#xff0c;它可以使互不相关的两个进程互相通信,并且在文件系统中可见&#xff0c;可以通过文件名来找到。 2.半双工的通信方式,进程通过文件IO来操作有名管道。 3.有名管道遵循先进先出原则,不支持lseek()。 2.有名管道的创建 配…

E70_433半双工无线模组,伪全双工方案

E70_433半双工无线模组&#xff0c;伪全双工方案 前言架构设计外侧输入模块外侧输出模块内侧发帧模块内侧接受模块 实现代码通用宏定义代码解析 通用工具函数代码解析 串口输入输出函数代码解析 核心业务代码发送模块代码解析 接收模块代码解析代码流程 结语附带 前言 要搞一个…

计算机双工模式,100M 全双工、100M 半双工、10M全双工几种模式分别测试

1. 首先核实是否有多台电脑同时上网&#xff0c;或是当前电脑有没有在进行P2P下载或在线视频之类比较占用网络带宽的操作&#xff0c;此操作可能导致宽带数据量过大影响稳定性。若存在此情况&#xff0c;请关闭些软件断开些联网设备&#xff0c;减少带宽使用测试。 2. 若有其他…

Linux 查看网卡全双工 还是半双工 以及设置网卡为半双工

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴! 请问各位兄弟,在Linux中怎么看网卡是全双工工作还是半双工工作?mii-tool Linux:~ # mii…

路由之静态路由配置

一、路由概念 二、路由表的形成 三、路由协议 静态路由 路由器之间的连接需要配置静态路由 首先创建一个局域网&#xff0c;给pc0和pc1分别配置ip地址。 创建三个不同网段的局域网分别给电脑配置ip地址&#xff0c;将三个连接到一个路由上。为路由器与局域网相连的端口&#…

路由器静态路由配置实验

简单配置: 1.连接设备 2.配置PC和服务器的IP地址和网关 3.在路由器配置接口的IP地址(作为网关) 4.实现PC之间的通信 5.分别命名交换机和路由器,并设置时间 6.实现PC1可以telnet和ssh管理SW2和R1 7.配置静态路由实现全网互通 8.开启web服务器,在4台PC上测试是否能访问 实验…

静态路由配置实验

题目&#xff1a; 目录 1、首先进行基础配置 2、创建环回接口并配置IP地址 3、配置静态路由 对r1&#xff0c;要配置除自身连接的3个网段以外的5个网段 对r2&#xff0c;要配置除自身连接的3个网段以外的5个网段,其中3.3.3.0/24网段已配过&#xff0c;则配剩余4个网段 对r…

华为简单静态路由配置

今天通过学习路由交换的知识&#xff0c;学会了配置简单的静态路由&#xff0c;所以我这里介绍一个简单的实 验&#xff0c;在开始之前&#xff0c;我们要先了解一下什么是路由&#xff1f; 路由 路由是指导报文转发的路径信息&#xff0c;通过路由可以确认转发IP报文的路径。…

vue 3.0 静态路由配置

今天研究了一下vue3.0的静态路由配置&#xff0c;分享一下。 首先我们现在项目中建立router文件夹&#xff0c;如下图所示&#xff1a; 404文件夹存放404页面&#xff0c;components文件夹存放首页界面&#xff0c;config为设置文件夹&#xff0c;diz存放具体的业务逻辑和界面…

计算机配置静态路由目标,静态路由的配置命令

用户需求: 某学校网络拓扑图如图所示,要求配置静态路由,实现计算机PC1、PC2和PC3互通。 直连路由直连路由出现在路由表的条件 (1)接口为“up/up”状态。 (2)接口已经完成了IP地址的配置。直连路由的检查 静态路由是指由网络管理员手工配置的路由信息,用于定义去往目的网络的…

路由基础(简单的静态路由配置)

目录 一.路由基础 1.路由信息获取方式 2.路由加表前的比较-优先级&#xff1b;度量值 3.路由转发的选择-最长掩码 4.静态路由应用场景及配置 1.路由信息获取方式 路由器依据路由表进行转发&#xff0c;要实现转发功能&#xff0c;路由器需要发现路由&#xff0c;三种常见…

四种静态路由配置方法

拓扑图如下&#xff1a; 接口IP地址如拓扑图所示&#xff0c;配置过程省略&#xff0c;ar1和ar3都开启了dhcp。过程省略。 ar1的路由表&#xff1a; 此时只有直连的1.0和2.0网段的IP。没有3.0网段的。 那怎么有3.0网段的呢&#xff1f;接下来介绍四种方法。 方法一&#xff1a…

Windows系统的静态路由配置

Windows电脑静态路由的配置&#xff0c;使电脑同时使用两个不同网段的IP 操作方法&#xff1a; 1.开始菜单&#xff0c;输入cmd&#xff0c;右击cmd.exe&#xff0c;选择以管理员身份运行 2.查看当前路由的配置 命令格式&#xff1a; ##查看静态路由 route print 输出结果…

华为静态路由配置

静态路由 静态路由(Static Router)是由管理员通过手动配置的方式创建的路由&#xff0c;可以让路由器便捷的获知到达目的网络的路由。在静态路由基础上也可使用负载均衡、路由备份等技术。 本文分别对静态路由、负载均衡、路由备份进行实验配置及配置完之后如何验证。 网络拓…

ENSP静态路由配置

拓扑图 实现结果&#xff1a; 1.pc1访问pc345走上面R1,R2&#xff0c;R2实现备份21.1.1.0/24&#xff0c;实现备份pc3456访问pc12走下面的R3,R4并实现等价路由&#xff0c;尽量减少路由条目&#xff0c;全网可达 2.R7代表运行商&#xff0c;所有pc均可访问 第一步&#xff1a…

静态路由配置全面详解,静态路由快速入门指南

操作步骤 配置各路由器接口的IP地址 以配置Router_1的GE0/0/0接口为例&#xff0c;其他接口配置与之类似&#xff0c;不再重复介绍。 a、如图2所示&#xff0c;依次选择“广域网互联 > 以太接口”&#xff0c;进入“以太接口”界面。 图2 以太接口界面 b、在“以太接口列…

12 路由器静态路由配置

借鉴网址&#xff1a;(28条消息) Packet Tracer 思科模拟器入门教程 之十一 路由器静态路由配置_柚子君.的博客-CSDN博客_思科模拟器新手详细教程 姓 名 彭彭头 实验日期 2022.04.26 学 号 实验序号 12 实验名称 路由器静态路由配置 一、实验目的及要求 掌握静态路由…