Linux 套接字编程基础

本文介绍了Linux下套接字编程的基础知识,包括套接字的结构、相关处理函数、socket通信过程,如socket、connect、bind、listen、accept等,并讨论了并发服务器的实现。此外,还提到了字节序转换、地址转换函数和字节流读取函数在套接字编程中的应用。
摘要由CSDN通过智能技术生成

套接口即网络进程的ID;网络通信归根到底即为进程间的通信;套接字中包含了端口号,用来确定进程,一个端口号一次只能分配给一个进程,即端口号与进程是一一对应的;

一、套接字的结构

1、IPv4套接字地址结构

  IPv4地址结构命名为sockaddr_in,定义在<netinet/in.h>头文件中,结构定义如下:

struct sockaddr_in {
    sa_family_t sin_family;    //IPV4协议为AF_INET,协议族
    in_port_t sin_port;        //16位端口号,网络字节序列
    struct in_addr sin_addr;   //32位IP地址
    unsigned char sin_zero[8]; //备用域;
};
struct in_addr{
    in_addr_t s_addr;          //32位IP地址,网络字节序列
} ;

2、通用套接字地址结构

struct sockaddr{
    sa_family_t sa_family;
    char sa_data[14]
}

通用套接字结构本质上和上面的IPv4套接字是一致的,通用套接字只是在函数调用的过程中用于参数的传递,定义时用sockaddr_in定义,在函数调用时通过类型转换来使用。可以参考sockaddr和sockaddr_in的区别 。套接字结构除了这两种常见的外还有基于IPv6和Unix域的结构sockaddr_in6,sockaddr_un等。

二、相关处理函数

1、字节排序函数

#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);    //返回网络字节序的值
uint32_t htonl(uint32_t host32bitvalue);    //返回网络字节序的值
uint16_t ntohs(uint16_t net16bitvalue);     //返回主机字节序的值
uint32_t ntohl(uint32_t net32bitvalue);     //返回主机字节序的值

其中,h代表host,n代表net,s代表short(两个字节),l代表long(4个字节),通过上面的4个函数可以实现主机字节序和网络字节序之间的转换,16bit和32bit分别用于端口号和IP地址。有时可以用任何地址则用INADDR_ANY,INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。

2、字节操作函数

  字节操作函数主要是用于操作结构体中的某几个字节,在处理套接字结构中有IP地址等字段,包含0字节却不是C字符串,需要特定的函数来进行处理。

#include <string.h>
void bzero(void *dest,size_t nbytes);
void bcopy(const void *src,void *dest,size_t nbytes);
int bcmp(const void *prt1,const void *ptr2,size_t nbytes);  //相等返回0,否则非0

void *memset(void *dest,int c,size_t len);
void *memcpy(void *dest,const void *src,size_t nbytes);
int memcmp(const void *ptr1,const void *ptr2,size_t nbytes); //相等返回0,否则非0

  以b打头的函数为支持套接口函数的系统所提供,mem为支持ANSI C库提供的函数;其中,bzero将指定数目的字节设置为0,bcopy将指定数目的字节从源字节串复制到目的字节串。bcmp比较两个字节串,相同返回0。memset将目标中指定数据的字节设置为指定的值(不一定是0),memcpy为复制,memcmp为比较,两者与前面类似。

3、地址转换函数

  一般使用ASCII字符串表示IP地址,也就是点分十进制数表示(218.170.19.1),但在套接字中使用32位网络字节序,保存的是二进制值,因此必须进行地址转换。

#include <arpa/inet.h>
in_addr_t inet_addr(const char *straddr);    //字符串有效返回网络字节序的IP地址,否则INADDR_NONE
int inet_aton(const char* straddr,struct in_addr *addrp);//字符串有效返回1,否则0
char* inet_ntoa(struct in_addr inaddr); //返回一个字符串指针

int inet_pton(int family, const char* str, void* addr);
//成功返回1,字符串无效返回0,出错返回-1
const char* inet_ntop(int family, const void* addr, char* str, size_t len);
//成功返回结果指针,出错返回NULL

/*说明
 *后面两个函数为新函数,支持IPv4和IPv6,family用来指定:AF_INET,AF_INET6
 *inet_ntop函数len为目标存储单元大小,str指针就是函数返回值
 */

   inet_aton将一个字符串转换为32位网络字节序二进制值,用结构in_addr存储。inet_addr功能相同(废弃,不使用),inet_ntoa进行相反的操作。
   
4、字节流读取函数

  在套接字通信中进行字节读取函数:read(),write()。与I/O中的读取函数略有区别,因为它们输入或输出的字节数比可能比请求的少。

ssize_t write(int fd, const void*buf,size_t nbytes);
ssize_t read(int fd,void *buf,size_t nbyte); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值