Linux —— 网络编程套接字

编程入门 行业动态 更新时间:2024-10-28 06:29:58

Linux —— <a href=https://www.elefans.com/category/jswz/34/1768814.html style=网络编程套接字"/>

Linux —— 网络编程套接字

目录

一,网络字节序

二,socket编程接口

sockaddr结构


源IP地址、目的IP地址,在IP数据包头部,有此两个IP地址;

端口号,是传输层协议的内容;

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程,告诉操作系统当前数据要交给哪个进程来处理;
  • IP地址+端口号能标识网络上的某台主机的某个进程;
  • 一个端口号只能被一个进程占用;

一个进程可以绑定多个端口号,但一个端口号不能被多个进程绑定;

源端口号、目的端口号,传输层协议(TCP、UDP)的数据段中有此两个端口号,描述“数据是谁发的,要发给谁”;

TCP协议(Transmission Control Protocol 传输控制协议)

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

UDP协议(User Datagram Protocol 用户数据报协议)

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

一,网络字节序

        内存中的多字节数据相当于内存地址有大小端之分,磁盘文件中的多字节数据相当于文件中的偏移也有大小端之分,网络数据流同样也有大小端之分;

如何定义网络数据流的地址:

  • 发送主机通常将发送缓冲区中的数据按内存从低到高的顺序发送;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此网络数据流的地址,先发出的数据是低地址,后发出的数据是高地址;
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节;
  • 不管这台主机是大端机还是小段机,都会按照TCP/IP协议规定的网络字节序来发送、接收数据;
  • 如当前发送主机是小段,需先将数据转成大端,否则忽略直接发送即可;

为使网络程序具有可移植性,同样C代码在大端机和小端机上编译后都能正常运行,可调用以下库函数做网络字节序和主机字节序的转换;

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • h,表示host,n表示network,l表示32位长整数,s表示16位短整数;
  • 如htonl表示32位长整数从主机字节序转换为网络字节序;
  • 如主机是小端字节序,这些函数将参数做相应的大小端转换,然后返回;
  • 如主机是大端字节序,这些函数不做转换,然后返回;

二,socket编程接口

socket常见API

//创建socket文件描述符(TCP/UDP,客户端+服务器)
int socket(int domain, int type, int protocol);//绑定端口号(TCP/UDP,服务器)
int bind(int socket, const struct sockaddr* address, socklen_t address_len);//开始监听socket(TCP,服务器)
int listen(int socket, int backlog);//接收请求(TCP,服务器)
int accept(int socket, struct sockaddr* address, socklen_t address_len);//建立连接(TCP,客户端)
int connect(int sockid, const struct sockaddr* addr, socklen_t addlen);

sockaddr结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,及UNIX Domain Socket;然而各种网络协议的地址格式并不相同;

  • IPv4、IPv6地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32位IP地址;
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET16;这样,只要取得某种sockadddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容;
  • socket API可以都用struct sockaddr*类型表示,在使用的时候需要强制转化sockaddr_in;这样的好处是程序的通用性,可以接收IPv4、IPv6,及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;

//socketaddr 结构
struct sockaddr{__SOCKADDR_COMMON (sa_);char sa_data[14];
};
//sockadddr_in 结构
struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port;struct in_addr_ sin_addr;unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE - sizeof (in_port_t) -sizeof (struct in_addr)];
};

虽然socket API的接口是sockaddr,但是真正在基于IPv4编程时,使用的数据结构是sockaddr_in;这个结构里主要有三部分信息:地址类型、端口号、IP地址;

//in_addr 结构
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;
};

in_addr用来表示一个IPv4的IP地址,其实就是一个32位的整数;

//UDP server
#include <iostream>    
#include <cstring>    
#include <unistd.h>    
#include <sys/types.h>    
#include <sys/socket.h>    
#include <netinet/in.h>    #define PORT 8081    int main()    
{    int sock = socket(AF_INET, SOCK_DGRAM, 0);    if(sock < 0){    std::cerr << "socket error" << std::endl;    return 1;    }    std::cout << "sock: " << sock << std::endl;    struct sockaddr_in local;    memset(&local, 0, sizeof(local));    local.sin_family = AF_INET;    local.sin_port = htons(PORT); //    local.sin_addr.s_addr = htonl(INADDR_ANY);    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0){    std::cout << "bind error " << std::endl;    return 1;    }    char message[1024];    for(; ;){    struct sockaddr_in peer;    socklen_t len = sizeof(peer);    ssize_t s = recvfrom(sock, message, sizeof(message)-1, 0, (struct sockaddr*)&peer, &len);    if(s > 0){    message[s] = '\0';    std::cout << "client# " << message << std::endl;    sendto(sock, message, strlen(message), 0, (struct sockaddr*)&peer, len);                                                               }    else{ //todo}    }    close(sock);    return 0;    
}

更多推荐

Linux —— 网络编程套接字

本文发布于:2023-11-15 06:53:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1595536.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:网络编程   Linux

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!