Linux套接字网络编程

1、OSI参考模型和TCP/IP模型

OSI协议参考模型,它是基于国际标准化组织(ISO)的建议发展起来的,它分为7个层次:应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。这个7层的协议模型虽然规定得非常细致和完善,但在实际中却得不到广泛的应用,其重要的原因之一就在于它过于复杂,但它仍是此后很多协议模型的基础。与此相区别的TCP/IP协议模型将OSI的7层协议模型简化为4层,从而更有利于实现和使用。两个模型具体如下:

                                                    

2、TCP/IP各层的任务

网络接口层:网络接口层是TCP/IP的最底层,负责将二进制流转换成数据帧,并进行数据帧的发送和接收。数据帧是网络传输的基本单元。

网络层:网络层负责在主机之间的通信中选择数据包的传输路径,即 路由。当网络收到传输层的请求后,使用路由算法来确定是直接交付数据包,还是把它传递给路由器,最后把数据包交给适当的网络接口进行传输。

传输层:负责实现应用程序之间的通信服务,又称为端到端通信,传输层要提供可靠的传输服务,以确保数据到达无差错、无乱序。为了达到这个目的,传输层协议软件要进行协商。传输层协议软件要把传输的数据流分为分组。

应用层:应用层是分层模型的最高层。应用程序使用相应的应用层协议,把封装好的数据交给传输层或是传输层接收数据并处理。

3、套接字的概念

①为一种特殊的IO接口,是一种文件描述符

②是一种常用的进程间的通信、本地、不同主机之间通信的方式

socket与网络络地址结构{协议,本地地址,本地端口}绑定

 

4、套接字的类型

①流式套接字:(SOCK_STREAM

流式的套接字可以提供可靠的、面向连 接的通讯流。它使用了TCP协议。TCP保证了数据传输的正确性和顺序性。

②数据报套接字:(SOCK_DGRAM

数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错,它使用数据报协议UDP

③原始套接字(SOCK_RAM)

原始套接字允许对低层协议如IPICMP直接访问,主要用于新的网络协议的测试等.

 

5、地址的结构及转换

对于主机的地址,它们通常都具有一定的地址数据结构,常用的地址结构有以下两种,之间为等价关系

 (1)

struct sockaddr
{
    unsigned short sa_family; //地址族,区分是IPV4协议和IPV6协议(AF_INET和AF_INET6)
    char sa_data[14]; //用于存放IP地址和端口号
};
(2)

struct sockaddr_in
{
    unsigned short sin_family;//地址族,为AF_INET和AF_INET6
    uint16_t sin_port;//端口号
    struct in_addr sin_addr;//IP地址
    unsigned char sin_zero[8];//未使用,填0
};
struct in_addr
{
    unsigned long s_addr;//32位的地址
}

在网络编程中,上述的两种结构通常不对第一种即sockaddr数据结构操作,而是使用与sockaddr等价的sockaddr_in数据结构操作

6、字节序转换

(1)字节序转换的原因:不同类型的 CPU 对变量的字节存储顺序可能不同:分为大端模式和小端模式。有的系统是低地址放数据的高字节,高地址放数据的低字节,即大端模式;而有的系统是低地址放数据的低字节,高地址放数据的高字节,即小端模式,而网络传输的数据顺序是一定要统一的,所以当内部字节存储顺序和网络字节顺序不同时,就一定要进行转换。

(2)字节序转换函数

头文件:#include <arpa/inet.h>

①从主机序转换到网络序

uint32_t htonl(uint32_t hostint32);//32位的数据传送

uint16_t htonl(uint16_t hostint16);//16位的数据传送

②从网络序转换到主机序

uint32_t ntohl(uint 32_t netint32);//32位的数据接收

uint16_t ntohl(uint 16_t netint16);//16位的数据接收


7、socket编程的C函数

①socket

函数原型:int socket(int domain,int type,int protocol);

头文件:#include <sys/socket.h>

函数的作用:创建新的socket套接字

参数:

domain:表示使用的地址类型,AF_INET表示IPV4,AF_INET6表示IPV6

type:①SOCK_STREAM:面向数据流(TCP)

        ②SOCK_DGRAM:使用不连续不可信赖的数据包连接(UDP)

        ③SOCK_RAM:提供原始网络协议存取

protocol:传输协议编号,设为0即可

返回值:执行成功,返回套接字的描述符;执行失败,返回-1


②bind

函数原型:int bind(int sockfd,struct sockaddr *my_addr,int addrlen);

头文件:#include <sys/socket.h>

               #include <sys/types.h>

函数的作用:绑定IP地址和端口号

参数:

sockfd:套接字描述符

my_addr:服务器的网络地址

addrlen:struct sockaddr结构的长度

返回值:执行成功,返回0;执行出错,返回-1.

注意:在绑定套接字前,通常定义一个结构体struct sockaddr_in变量,用bzero函数对结构体内容清0,在对每个成员进行初始化,最后再强制类型转换为(struct sockaddr *)的指针传入绑定参数即可。具体初始化过程如下,以服务器为例(定义了一个变量 struct sockadddr_in servaddr;):

bzero(&servaddr, sizeof(servaddr));
 servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port = htons(SERV_PORT);


③connect

函数原型:int connect (int sockfd,struct sockaddr *serv_addr,int addrlen);

头文件:#include <sys/socket.h>

函数的作用:建立socket连线,通常为客户端连接服务器所用

参数:

sockfd:套接字描述符

serv_addr:要连接的服务器的IP地址

addrlen:struct sockaddr的长度

返回值:执行成功,返回0;执行出错,返回-1.


④listen

函数原型:int listen(int sockfd,int backlog);

头文件:#include <sys/socket.h>

函数的作用:监听网络,等待连接

参数:

sockfd:套接字描述符

backlog:允许接入的客户端数目

返回值:执行从成功 ,返回0;执行出错,返回-1.

注意:listen并没有开始接收连线,只是设置socket的listenz模式,真正连线的是在accept中


⑤accept

函数原型:int accept(int sockfd,struct sockaddr *addr,int *addrlen);

头文件:#include <sys/socket.h>

函数的作用:接受网络连接,客户端连接和三次握手在accept中发生

参数:

sockfd:套接字描述符

addr:连接成功,用于填充客户端的地址

addrlen:struct sockaddr的长度

返回值:执行成功,返回新的套接字描述符;执行失败,返回-1


⑥send

函数原型:int send(int sockfd,const void *msg,int len,unsigned int falgs);

头文件:#include <sys/socket.h>

函数的作用:经过socket向对方发送数据

参数:

sockfd:accept产生的新的套接字描述符

msg:要发送的数据存放的地址空间首地址

len:数据的长度

falgs:一般设置为0

返回值:执行成功,返回实际发送数据的字节数;执行失败,返回-1.


⑦recv

函数原型:int recv(int sockfd,void *buf,int len,int falgs);

头文件:#include <sys/socket.h>

函数的作用:通过socket接收数据

参数:

sockfd:accept产生的新的套接字描述符

buf:读取到的数据存放空间的首地址

len:接收数据的最多长度

falgs:设置为0

返回值:执行成功,返回实际接收到的数据的字节数;执行失败,返回-1


7、点分十进制形式和二进制形式间的转换

(1)点分十进制形式转换为二进制形式:

①inet_addr

函数原型:unsigned long int inet_addr(const char *cp);

参数:

cp:放置如“192.168.1.12”的点分十进制地址(字符串形式)

返回值:执行成功,返回对应的二进制数;执行出错,返回-1


②inet_pton

函数原型:int inet_pton(int af,char *src,void *dst);

参数:

af:地址类型,AF_INET和AF_INET6

src:要转换的点分十进制地址

dst:转换后的网络地址

返回值:执行成功,返回1,;格式无效,返回0;执行失败,返回-1.


(2)二进制形式转换为点分十进制形式

inet_ntop

函数原型:const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);

参数:

af:地址类型,AF_INET和AF_INET6

src:要转换的二进制地址

dst:转换后的点分十进制地址

size:保存文本字符串的缓冲区的大小

返回值:执行成功,返回地址字符串指针;执行出错,返回NULL


            





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值