socket网络编程

本文只介绍基于IPv4的socket网络编程

端口号

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

认识TCP协议

此处我们先对TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识; 后面我们再详细讨论TCP的一些细节问题.

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

认识UDP协议 

此处我们也是对UDP(User Datagram Protocol 用户数据报协议)有一个直观的认识, 后面再详细讨论.

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

网络字节序 

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

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

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

  • 这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数
  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回
  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回

套接字编程种类

  1. 域间套接字编程---同一机器内
  2. 原始套接字编程---网络工具
  3. 网络套接字编程---用户间的网络通信

我们这里讲网络套接字编程

socket 常见API

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

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

sockaddr 结构

sockaddr_in 结构 

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

in_addr结构

socket编程接口 

socket

创建套接字,返回值是网络文件描述符 (TCP/UDP, 客户端 + 服务器)

参数:

domain: 创建套接字的域,我们这里填AF_INET表示使用ipv4的网络协议

type:套接字对应的类型,SOCK_STREAM字节流套接子,SOCK_DGRAM数据报套接字,就是什么的TCP协议是面向字节流的,UDP协议是面向数据报的

protocol:协议类型,我们这里理,设为0先

返回值,就是网络文件描述符

bind 

绑定套接字和端口号  (TCP/UDP, 服务器)

绑定的IP地址和端口号都在addr里,这个结构体需要我们自己设置,再传进去

伪代码:

struct sockaddr_in

{

        sin_family;//创建套接字的域  AF_INET

        sin_port;//端口号

        sin_addr;//IP地址

};

recvfrom

接收发给套接字的网络信息

参数很好理解,flags设为0,后面的结构体是输出型参数,记录是谁发的 

send

向套接字发送信息

地址转换函数

本文只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位的IP 地址但是我们通常用点分十进制的字符串表示IP地址,以下函数可以在字符串表示 和in_addr表示之间转换

头文件

#include <arpa/inet.h>

字符串转in_addr的函数

这个函数不仅把字符串转为32IP地址,还转为网络字节序了 

 in_addr转字符串的函数

简单的UDP网络程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲代码的柯基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值