socket编程预备

发布于:2025-06-01 ⋅ 阅读:(96) ⋅ 点赞:(0)

1.进程是人在系统中的代表,只要进程拿到数据就相当于人拿到数据

2.数据传输到主机不是目的而是手段。数据到达主机内部,再交给主机内的进程才是目的

3.进程(内存)--> 网卡-->网络

4.网络通信的本质是两个不同主机的进程进行数据交互

或者说:网络通信的本质是进程间通信

5.端口号是传输层的内容,大小为2字节,用来标识一个进程的唯一性

6.端口号 VS pid

(1)不是所有进程都要进行网络通信,即进程一定有pid,但是不一定有端口号

(2)从技术手段上来说,用pid计数是可行的,但是pid是一个系统概念,若pid变化了,网络也要跟着变化,两者是解耦的

7.IP地址表示全网唯一的主机

port表示该主机内唯一的网络进程

IP+port=全网内唯一的一个进程=socket

----->网络通信的本质是全网内唯二的两个进程间通信

8.一个端口号只能对应一个进程,但是一个进程可以对应多个端口号

9.端口号的范围:0~65535,其中0~1023是知名端口号,作为一些公共熟知的端口使用;1024~65535是由操作系统动态分配的端口号

10.传输层的典型代表:TCP协议,UDP协议

(1)TCP:有连接,可靠传输,面向字节流

(2)UDP:无连接,不可靠传输,面向数据报

11.网络字节序:凡是到达网络的数据必须是以大端形式存储的

12.socket编程的接口(已使用UDP协议为例)

<1>套接字类型:

  • 流式Socket(SOCK_STREAM):可靠双向字节流(TCP)
  • 数据报Socket(SOCK_DGRAM):无连接数据包(UDP)
  • 原始Socket(SOCK_RAW):直接访问IP层

地址结构

struct sockaddr_in {
    sa_family_t    sin_family;  // AF_INET/AF_INET6
    in_port_t      sin_port;    // 16位端口号(网络字节序)
    struct in_addr sin_addr;    // IPv4地址
};

<2>int socket(int domain, int type, int protocol);

函数原型

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

作用:创建网络通信端点的核心函数,属于套接字API的基础部分

参数介绍

  1. domain(地址族)
    • AF_INET:IPv4协议(常设置为这种形式)
    • AF_INET6:IPv6协议
    • AF_LOCAL(或AF_UNIX):本地进程间通信(IPC)
    • AF_PACKET:底层数据包访问
  2. type(套接字类型)
    • SOCK_STREAM:面向连接的流式套接字(TCP)
    • SOCK_DGRAM:无连接的数据报套接字(UDP)
    • SOCK_RAW:原始套接字(直接访问网络层)
    • SOCK_SEQPACKET:可靠的数据包序列传输
  3. protocol(协议类型)
    • 通常设为0,系统会自动选择指定domain和type下的默认协议
    • 特殊需求时可指定具体协议号(如IPPROTO_TCP

返回值:

  • 成功:返回新的套接字描述符(非负整数)
  • 失败:返回-1,并设置errno表示错误类型

<3>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

函数原型

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

作用:bind() 函数是网络编程中用于将套接字与特定地址和端口绑定的关键函数,通常用于服务端程序

参数介绍

  1. sockfd
    • 通过socket()函数创建的套接字描述符
  2. addr
    • 指向sockaddr结构体的指针,包含要绑定的地址和端口信息
    • 实际使用时通常转换为特定协议的结构体(如sockaddr_in
  3. addrlen
    • 地址结构体的长度(字节数)

返回值:

  • 成功:返回0
  • 失败:返回-1,并设置errno表示错误类型

<4>ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

函数原型

#include <sys/types.h>
#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);

作用:recvfrom() 函数是网络编程中用于从套接字接收数据的核心函数,特别适用于无连接协议(如UDP)或需要获取发送方地址信息的场景

参数介绍

  1. sockfd
    • 套接字描述符(需为已绑定的UDP套接字或面向无连接的套接字)。
  2. buf
    • 指向接收缓冲区的指针,用于存储接收到的数据。
  3. len
    • 缓冲区长度(字节数)。
  4. flags
    • 控制接收行为的标志位(常用值):
      • 0:默认阻塞接收。
      • MSG_DONTWAIT:非阻塞模式。
      • MSG_PEEK:查看数据但不移除缓冲区。
      • MSG_WAITALL:等待接收完整数据(不适用于UDP)。
  5. src_addr
    • 输出参数,指向sockaddr结构体的指针,用于存储发送方地址信息。
    • 若无需获取发送方地址,可设为NULL
  6. addrlen
    • 输入/输出参数:
      • 输入时:指定src_addr结构体的长度。
      • 输出时:返回实际填充的地址长度。
    • 若无需获取发送方地址,可设为NULL

返回值

  • 成功:返回实际接收的字节数(可能小于len)。
  • 错误:返回-1,并设置errno表示错误类型(如EAGAIN非阻塞模式下无数据可读)。
  • 对端关闭:返回0(仅适用于面向连接的套接字,UDP中不适用)。

<5>ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

函数原型

#include <sys/types.h>
#include <sys/socket.h>

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);

作用:sendto() 函数是网络编程中用于通过无连接套接字(如UDP)发送数据的核心函数。它允许指定目标地址,适用于需要向特定接收方发送数据报的场景。

参数介绍

  1. sockfd
    • 套接字描述符(需为已绑定的UDP套接字或面向无连接的套接字)。
  2. buf
    • 指向待发送数据的缓冲区指针。
  3. len
    • 要发送的数据长度(字节数)。
  4. flags
    • 控制发送行为的标志位(常用值):
      • 0:默认阻塞发送。
      • MSG_DONTWAIT:非阻塞模式。
      • MSG_CONFIRM:通知协议层链路层缓存有效(仅部分系统支持)。
      • MSG_MORE:后续还有数据要发送(如TCP的Nagle算法优化)。
  5. dest_addr
    • 指向sockaddr结构体的指针,指定目标地址和端口。
    • 若套接字已连接(通过connect()),可设为NULL
  6. addrlen
    • 目标地址结构体的长度(字节数)。

返回值

  • 成功:返回实际发送的字节数(可能小于len)。
  • 错误:返回-1,并设置errno表示错误类型(如EAGAIN非阻塞模式下无法立即发送)。

网站公告

今日签到

点亮在社区的每一天
去签到