Linux网络学习_socket套接字
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux网络学习_socket套接字相关的知识,希望对你有一定的参考价值。
套接字
- 概念
- Socket(套接字)是一种通讯机制,它包含一整套的调用接口和数据结构的定义,它给应用进程提供了使用如TCP/UDP等网络协议进行网络通讯的手段。
- Linux中的网络编程通过Socket接口实现,Socket即是一种特殊的IO,提供对应的文件描述符。
- 一个完整的Socket都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口}(五元组);
- 每一个Socket有一个本地的唯一Socket,由操作系统分配。
- 创建Socket
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol)
- 返回:成功返回描述符,出错返回-1
- Socket创建在内核中,若创建成功则返回内核文件描述表中的socket描述符。
参数:- domain
- AF_INET:IPv4因特网域
- AF_INET6:IPv6因特网域
- AF_UNIX:unix域
- AF_UNSPEC:未指定
- type
- SOCK_STREAM:
- 流式的套接字可以提供可靠的、面向连接的通讯流。他使用了TCP协议。TCP保证了数据传输的正确性和顺序性。
- SOCK_DGRAM:
- 数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。使用数据报协议UDP协议。
- SOCK_RAW:
- 原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。
- SOCK_SEQPACKET:
- 长度固定、有序、可靠的面向链接报文传递。
- SOCK_STREAM:
- protocol
- 通常为0,表示按给定的域和套接字类型选择默认协议
- domain
- 字节序
- 不同体系结构的主机使用不同的字节序存储器来保存多字节整数。字节存储顺序不同,有的系统是高位在前,低位在后(大端字节序),而有的系统是低位在前,高位在后(小端字节序)。
- 字节序分为大端 字节序(big-endiane)和小端字节序(little-endian)。
- 网络协议使用网络字节序即大端字节序。
- 字节序转换函数
- 网络传输的所有数据是一定要统一顺序的(网络字节序)。所以对于内部字节表示顺序和网络字节顺序不同的机器,就一定要对数据进行转换:
- h–host主机,n–net网络,l–long,s–short
- uint32_t htonl(uint32_t hostlong);
- 将一个32位整数由主机字节序转换成网络字节序
- uint16_htons(uint16_t hostshort);
- 将一个16位整数由主机字节序转换成网络字节序
- uint32_t ntohl(uint32_t netlong);
- 将一个32位整数由网络字节序转换成主机字节序
- uint16_t ntohs(uint16_t netshort);
- 将一个16位整数由网络字节序转换成主机字节序
- 通用地址结构
#include <sys/socket.h>
struct sockaddr{
unsigned short sa_family; /*Internet地址族,AF_xxx*/
char sa_data[14]; /*14 bytes的协议地址*/
};
- sa_data 包含了一些远程电脑的地址、端口和套接字的数目,它里面的数据是杂融在一起的。
- sa_family 一般来说,IPv4使用AF_INET。
- 在传递给需要地址结构的函数时,把指向该结构的指针转换成(struct sockaddr*)传递进去。
- 因特网地址结构
struct in_addr{
in_addr_t s_addr; /*ipv4地址*/
};
struct sockaddr_in{
short int sin_family; //Internet地址族如AF_INET(主机字节序)
unsigned short int sin_port; //端口号,16位值(网络字节序)
struct in_addr sin_addr; //Internet地址,32位IPv4地址(网络字节序)
unsigned char sin_zero[8]; //添0(为了格式对齐的填充位)
};
因特网地址结构(sockaddr_in)和通用地址结构(sockaddr)类型是等效的,可以互相转换,通常使用sockaddr_in更为方便。
- IPv4地址族和字符地址间的转换
(1)网络字节序转换成点分十进制:
#include <arpa/inet.h>
const char* inet_ntop(
int domain,
const void* restrict addr,
char* restrict str,
socklen_t size );
- 返回:成功返回地址字符串指针,出错返回NULL
(2)点分十进制转换为网络字节序
#include <arpa/inet.h>
int inet_pton(
int domain,
const char* restrict str,
void* restrict addr);
- 返回:成功返回1,无效格式返回0,出错返回-1
- 参数
- domain:Internet地址族,如AF_INET
- addr:Internet地址,32位IPv4地址(网络字节序)
- str:地址字符串(点分十进制)指针
- size:地址字符串大小
- 填写IPv4地址族结构案例
struct sockaddr_in sin; //定义一个aockaddr_in结构体
char buf[16];
memset(&sin,0,sizeof(sin)); //内存清0
sin.sin_family = AF_INET; //填写Internet地址族
sin.sin_port = htons((short)3001); //填写端口号(网络字节序)
//填充sin_addr
if(inet_pton(AF_INET,"192.168.2.1",&sin.sin_addr.s_addr)<=0)
{
//错误处理
}
printf("%s\\n",inet_ntop(AF_INET,
&sin.sin_addr.s_addr,
buf,
sizeof(buf)));
以上是关于Linux网络学习_socket套接字的主要内容,如果未能解决你的问题,请参考以下文章