Linux C网络编程

1.Linux套接字

1.1 套接字介绍

套接字(Sockets),即为网络进程ID,是由运行这个进程的计算机的IP地址和这个进程使用的端口(Port)组成.

可以只用'netstat-all' 查看当前系统中网络应用进程的套接字和端口. 可以使用 > 输出重定向到文件.

1.2 套接字的结构

Linux在头文件<sys/socket.h>中定义了通用的套接字结构类型,可供不同协议调用

  1. struct sockaddr
  2. {
  3. unsigned short int sa_family; //表示套接字的协议类型,如常见的IPv4,IPv6
  4. unsigned char sa_data[14]; //14个字节的协议地址,包含了IP地址和端口
  5. }

除了sockaddr之外,Linux还在<netinet/in.h>中定义了另外一种结构类型 sockaddr_in ,它和sockaddr等效且可以互相转换.通常用于TCP/IP协议

  1. struct sockaddr_in
  2. {
  3. int sa_len; //长度单位,通常使用默认值16
  4. short int sa_family; //协议族
  5. unsigned short int sin_port; //端口号
  6. struct in_addr sin_addr; //IP地址
  7. unsigned char sin_zero[8]; //填充0,保证与struct sockaddr同样大小
  8. }

对其中struct in_addr sin_addr说明如下

  1. struct sin_addr
  2. {
  3. in_addr_t s_addr; //32 IPv4地址
  4. }

常见协议对应的sa_famliy值

可选值 说明
AF_INET IPv4协议
AF_INET6 IPv6协议
AF_LOCAL UNIX协议
AF_LINK 链路地址协议
AF_KEY 密钥套接字

2.Linux网络操作函数

2.1 字节顺序转换函数族

往往网络上的不同机器,数据存储模式不同,小型机通常为小端模式,大型机为大端模式.所以往往需要字节转换.

Linux 提供了htonl ,htons,ntohl ,ntohs函数处理大端和小端模式转换

解释:htonl/htons:host to network long/short ;同理 ntohl/ntohs:network to host long/short

  1. #include <arpa/inet.h>
  2. unit32_t htonl(unit32_t hostlong);
  3. unit16_t htons(unit16_t hostshort);
  4. unit32_t ntohl(unit32_t netlong);
  5. unit16_t ntohs(unit16_t netshort);

32为long数据通常存放IP地址,16为通常存放端口号

htonl:将32为PC机数据(小端)转为32位网络传输数据(大端)

2.2 字节操作函数族

套接字与字符串不同,套接字是多字节数据而不是以空字符串结尾.Linux提供了若干函数,在内存上直接操作套接字

2.2.1

第一组函数是与BSD系统兼容的函数,包括bzero,bcopy,bcmp.

bzero:将参数s指定的前n个字节设置为0,通常用来对套接字地址清零

  1. #include <strings.h>
  2. void bzero(void *s,size_t n);

bcopy:从参数src指定的内存区域,拷贝指定数目字节内容到dest指定内存区域

  1. #include <strings.h>
  2. void bcopy(const void* s1,void *dest,size_t n);

bcmp:用于比较是参数s1和参数s2指定内存区域的前n字节.如果相同返回0,否则返回非0

  1. #include <strings.h>
  2. int bcmp(const void *s1,const void *s2,size_t n);

2.2.2

2.3 IP地址转换函数族

IP地址通常是点分十进制表示,Linux网络编程中会使用32二进制值.Linux提供了若干函数保证二者相互转换

2.4 域名转换函数族

实际网络编程中往往会遇到www.baidu.com这样的域名Linux提供了函数让域名转为IP地址和让IP地址转域名

3. 套接字编程

3.1 创建套接字描述符函数

Liunx使用socket函数创建套接字描述符

  1. #include <sys/type.h>
  2. #include <sys/socket.h>
  3. int socket(int domain,int type,int protocol);

函数调用成功,则返回套接字描述符(正整数),否则返回-1

参数说明

  • domain: 套接字协议族,支持类型如下

    协议族名称 描述
    AF_UNIX,AF_LOCAL 本地交互协议
    AF_INET IPv4协议
    AF_INET6 IPv6协议
    ... ...
  • type:指定当前套接字类型

    类型名称 描述
    SOCK_STREAM 数据流
    SOCK_DGRAM 数据报
    SOCK_SEQPACKET 顺序数据报
    SOCK_RAW 原始套接字
    SOCK_RDM 可靠传递消息
    SOCK_PACKET 数据包
  • protoclo:通常情况下设置为0,表示使用默认协议

3.2 绑定套接字函数

在创建套接字后需要将本地地址和套接字绑定,可以调用bind函数

  1. #include <sys/type.h>
  2. #include <sys/socket.h>
  3. int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

sockfd是创建套接字时对于的套接字描述符.addr是本地地址.addrlen是套接字对应的地址结构长度;

bind函数执行成功返回0,否则返回-1

bind函数绑定模式有5种:

...等待更新

3.3 建立连接函数

使用socket函数建立套接字并绑定地址后,即可使用connect函数和服务器建立连接

  1. #include <sys/type.h>
  2. #include <sys/socket.h>
  3. int connect(int sockfd,const struct sockaddr *addr,socken_t addrlen);

参数sockfd是套接字创立后函数socket返回的套接字描述符;

参数addr指定远程服务器的套接字地址,包括服务器地址和端口号;

参数addrlen 指定套接字地址长度;

调用connect函数成功后,返回0,否则为-1

3.4 倾听套接字切换函数

socket函数直接创立的是主动套接字,用来发送请求的.如果是服务器需要倾听套接字,接受请求.使用listen函数将套接字转换为倾听套接字

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. int listen(int sockfd,int backlog);

参数sockfd使套接字描述符;backlog是请求队列的最大长度

baclog的作用:

...待更新

3.5接受连接函数

当服务器接收到一个连接后,可以使用函数accept从倾听套接字的完成连接队列中接受一个连接。如果完成连接队列为空,则进程进入睡眠。

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. int accept(int sockfd,struct sockaddr *addr ,socklen_t *addrlen);

3.6 关闭连接函数

  1. #include <unistd.h>
  2. int close(int fd);

3.7 套接字读写函数

  1. int read(int fd,char *buf,int len);
  2. int write(int fd,char *buf,int len);

3.8 套接字地址获取函数

  1. #include <sys/socket.h>
  2. int getsockname(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
  3. int getpeername(int sockfd,struct sockaddr *addr,socklen_t *addrlen);

3.9 发送和接受函数

  1. #include <sys/type.h>
  2. #include <sys/socket.h>
  3. ssize_t send(int socketfd,const void *buf,size_t len,int flags);
  4. ssize_t recv(int socketfd,const void *buf,size_t len,int flags);

4. Linux TCP编程

4.1 TCP工作流程

  • 服务器先用socket函数建立套接口,用这个套接口完成通信的监听和数据收发
  • 服务器利用bind函数绑定一个IP地址和端口号,使套接口与指定端口号,IP地址相关联
  • 服务器调用listen函数,使服务器和这个端口和IP处于监听状态,等待网络中某一客户的连接请求
  • 客户机用socket函数建立套接口,设定远程IP和端口.
  • 客户机调用connect函数连接远程计算机的指定的端口
  • 服务器调用accept函数接受远程计算机的连接请求,建立起与客户机之间的通信连接
  • 连接连接后,客户机里用write函数或者send函数乡socket中写入数据,也可以使用read函数或recv函数读取服务器发送来的数据
  • 服务器利用read函数或者recv函数读取客户机发送来的数据,也可以使用write函数或者send函数来发送数据
  • 完成通信后,使用close函数关闭socket连接

5. Linux UDP编程

待更新...

Linux C编程的更多相关文章

  1. 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"

    [深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...

  2. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  3. 学习linux/unix编程方法的建议(转)

    假设你是计算机科班出身,计算机系的基本课程如数据结构.操作系统.体系结构.编译原理.计算机网络你全修过 我想大概可以分为4个阶段,水平从低到高从安装使用=>linux常用命令=>linux ...

  4. Linux系统编程温故知新系列 --- 01

    1.大端法与小端法 大端法:按照从最高有效字节到最低有效字节的顺序存储,称为大端法 小端法:按照从最低有效字节到最高有效字节的顺序存储,称为小端法 网际协议使用大端字节序来传送TCP分节中的多字节整数 ...

  5. linux系统编程之错误处理

    在linux系统编程中,当系统调用出现错误时,有一个整型变量会被设置,这个整型变量就是errno,这个变量的定义在/usr/include/errno.h文件中 #ifndef _ERRNO_H /* ...

  6. storysnail的Linux串口编程笔记

    storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...

  7. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

  8. linux网络编程 no route to host 解决方案

    linux网络编程 no route to host 解决方案 [整合资料] (2013-05-13 21:38:12) 转载▼ 标签: net iptables it 分类: Linux 参考资料h ...

  9. 初探linux内核编程,参数传递以及模块间函数调用

    一.前言                                  我们一起从3个小例子来体验一下linux内核编程.如下: 1.内核编程之hello world 2.模块参数传递 3.模块间 ...

  10. linux脚本编程技术

    linux脚本编程技术 一.什么是脚本 脚本是一个包含一系列命令序列的可执行(777)文本文件.当运行这个脚本文件时,文件中包含的命令序列将得到自动执行. 二.脚本编程 #!/bin/sh 首行固定格 ...

随机推荐

  1. 【ABAP系列】SAP ABAP ALV合计或者小计 添加自定义文本

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP ABAP ALV合计或者小计 ...

  2. Redis--小小总结

    1.基本定义 memcached是纯粹的key-value内存数据库,也可能不应该叫数据库,应该叫另类缓存技术: Redis是一个基于内存的高性能key-value数据库:将数据全部加载到内存中,并定 ...

  3. [2019杭电多校第五场][hdu6629]string matching(扩展kmp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629 题意求字符串的每个后缀与原串的最长公共前缀之和. 比赛时搞东搞西的,还搞了个后缀数组...队友一 ...

  4. 基于Java的大整数运算的实现(加法,减法,乘法)学习笔记

    大整数,顾名思义就是特别大的整数. 一台64位的机器最大能表示的数字是2的64次方减一: 18446744073709551615 java语言中所能表示的整数(int)最小为-2147483648 ...

  5. 知乎使用selenium反爬虫的解决方案

    from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOp ...

  6. 生日蛋糕 (poj1190) (dfs剪枝)

    [题目描述] 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为 ...

  7. SCUT - 297 - 狂符「幻视调律(Visionary Tuning)」 - 重链剖分

    https://scut.online/p/297 一般的树剖是关于点权的,但是突发奇想好像边权也是一样的.做一些小改动. #include<bits/stdc++.h> #define ...

  8. CSS3 (border-radius)深度探析

    border-radius 为元素添加圆角边框 <div class = "demo"></div> .demo{ width:100px; height: ...

  9. Scala本地安装

    一.下载 https://www.scala-lang.org/download/ 这里我选择Scala2.10.4版本 二.安装 安装比较简单  和jdk类似 点击一路安装: 选择自己的路径 完成 ...

  10. ORA-00911: invalid character 错误解决

    多数情况如下: 控制面板--系统和安全---系统--高级系统设置--高级--环境变量--系统变量中 变量名:NLS_LANG 变量值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK ...