网络编程(Socket编程接口一)

本文详细介绍了网络编程中的字节序转换,包括IPv4的点分十进制数串与网络字节序之间的转换,并讨论了IPv4/IPv6通用的方法。此外,还详细阐述了Socket接口的创建、关闭、属性设置、绑定、监听、连接、接受、发送及接收等操作。最后,探讨了TCP基本流程和实践中的注意事项。
摘要由CSDN通过智能技术生成

1 接口

1.1 转换操作

转换操作主要分为三类:字节序转换操作、IP地址转换操作和主机名转换操作。

1.1.1 字节序转换操作

在这里插入图片描述

1.1.2 IP地址转换操作

在这里插入图片描述
IPv4地址结构:

struct in_addr {
    in_addr_t s_addr;
};

IPv4地址类型:

typedef unsigned int in_addr_t;

套接字地址结构:

struct sockaddr {
    unsigned short sa_family; // 套接字地址簇类型,为AF_INET
    char sa_data[14];         // 套接字地址数据(14位的协议地址)
};

IPv4套接字地址结构:

struct sockaddr_in{
    short sin_family;         // 套接字地址簇类型,为AF_INET
    unsigned short sin_port;  // 端口号,网络字节序
    struct in_addr sin_addr;  // IP地址,网络字节序
    unsigned char sin_zero[8];// 填充字节
};

sin_zero[8]用来保证结构体struct sockaddr_in的大小和结构体struct sockaddr的大小相等。

IPv6套接字地址结构:

struct sockaddr_in6{
   uint8_t sin6_len;           //IPv6 为固定的24 字节长度
   sa_family_t sin6_family;    //套接字地址簇类型,为AF_INET6
   in_port_t sin6_port;        //16 位端口号,网络字节序
   uint32_t sin6_flowinfo;     //32 位流标签
   struct in6_addr sin6_addr;  //128 位IP地址
}

1.2 ipv4专用

1.2.1 点分十进制数串转网络字节序长整型

推荐方式:

int inet_aton(const char *string, struct in_addr*addr);

参数说明:

参数 含义
string 点分十进制IP地址字符串
addr 网络字节序长整型IP地址

返回值说明:

返回值 含义
0 成功
非0 失败

示例:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
 
int main(int argc,char* argv[]){
    if(2 != argc){
        printf("usage:%s <ip>\n",argv[0]);
        return 1;
    }
    struct in_addr addr;
    int res = inet_aton(argv[1],&addr);
    if(0 == res){
        perror("inet_aton error");
        return 1;
    }
    printf("res:%d\n%s = 0x%08x",res,argv[1],addr);
 
    return 0;
}

旧方式:

in_addr_t inet_addr(const char* string);

参数说明:

参数 含义
string 点分十进制IP地址字符串

返回值说明:

返回值 含义
INADDR_NONE 失败
非INADDR_NONE 网络字节序长整型IP地址

示例:

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
 
int main(int argc,char* argv[]){
    if(2 != argc){
        printf("usage:%s <ip>\n",argv[0]);
        return 1;
    }
    in_addr_t addr = inet_addr(argv[1]);
    if(INADDR_NONE == addr){
        perror("inet_addr error");
        return 1;
    }
    printf("%s = 0x%08x",argv[1],addr);
 
    return 0;
}
1.2.2网络字节序长整型转点分十进制数串
char* inet_ntoa(struct in_addr addr);

参数说明:

参数 含义
addr 网络字节序长整型IP地址

返回值说明:

返回值 含义
非NULL 点分十进制IP地址字符串
NULL 失败
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
 
int main(int argc,char* argv[]){
    if(2 != argc){
        printf("usage:%s <num>\n",argv[0]);
        return 1;
    }
    struct in_addr addr;
    addr.s_addr = strtol(argv[1],NULL,16);
    char* ip = inet_ntoa(addr);
    if(NULL == ip){
        perror("inet_ntoa error");
        return 1;
    }
    printf("0x%x = %s",addr.s_addr,ip);
 
    return 0;
}

1.3 IPv4/IPv6通用(推荐)

1.3.1 点分十进制数串转网络字节序长整型
int inet_pton(int af, const char *src, void *dst);

参数说明:

参数 含义
af 地址族:AF_INET/AF_INET6
src 点分十进制IP地址字符串
dst 网络字节序长整型IP地址

返回值说明:

返回值 含义
<0 失败
0 af和src格式不对

示例:

#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
 
int main(int argc,char* argv[]){
    char ip[INET_ADDRSTRLEN];
    if(argc == 1){
        scanf("%s",ip);
    }else if(2 != argc){
        printf("usage:%s <ip>\n",argv[0]);
        return 1;
    }
    struct in_addr addr;
    memset(&addr,0,sizeof(addr));
    if(1 != inet_pton(AF_INET,(argc == 1?ip:argv[1]),&addr)){
        perror("inet_pton err");
        return 1;
    }
    printf("%x\n",addr.s_addr);
}
1.3.2 网络字节序长整型转点分十进制数串
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)

参数说明:

参数 含义
af 地址族:AF_INET/AF_INET6
src 网络字节序长整型IP地址
dst 点分十进制IP地址字符串
cnt 缓存区dst的大小

返回值说明:

返回值 含义
NULL 失败
非NULL dst指针

示例:

#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
 
int main(int argc,char* argv[]){
    if(2 != argc){
        printf("usage:%s <dec num>\n",argv[0]);
        return 1;
    }
    struct in_addr addr;
    memset(&addr,0,sizeof(addr));
    addr.s_addr = strtol(argv[1],NULL,16);
    char ip[INET_ADDRSTRLEN];
    if(NULL == inet_ntop(AF_INET,&addr,ip,sizeof(ip))){
        perror("inet_ntop err");
        return 1;
    }
    printf("%s\n",ip);
}

示例:

#include <iostream>
#include <arpa/inet.h>
 
using namespace std;
 
int main(){
    cout << sizeof(short) << endl;
    short s = 0x1234;
    cout << hex << s << endl; 
    cout << hex << htons(s) << endl;
    cout << sizeof(long) << endl;
    int l = 0x12345678; 
    cout << hex << l << e
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值