1 Socket 是什么

Socket(套接字),就是对 网络上进程通信端点抽象。一个 Socket 就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制

从所处的位置来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信交互的接口。如下图所示:

2 Socket 类型

2.1 标准套接字

标准套接字是在传输层使用的套接字,分为流式套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM)。

标准套接字在接收和发送时只能操作数据部分(TCP Payload / UDP Payload),而不能对 IP 首部或TCP 首部和 UDP 首部进行操作。

2.1.1 流套接字(SOCK_STREAM)

流套接字(SOCK_STREAM)用于提供 面向连接(可靠)的数据传输服务。

流套接字保证数据能够实现无差错、无重复发数据,并按顺序接收。

流套接字(SOCK_STREAM)使用 TCP(The Transmission Control Protocol)协议 进行数据的传输

2.1.2 数据报套接字(SOCK_DGRAM)

数据报套接字(SOCK_DGRAM)用于提供 无连接(不可靠)的数据传输服务。

数据报套接字不保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。

数据报套接字(SOCK_DGRAM)使用 UDP(User DatagramProtocol)协议 进行数据的传输

2.2 原始套接字(SOCK_RAW)

原始套接字(SOCK_RAW)可以做到标准套接字做到的事,更可以做到标准套接字做不到的事。

原始套接字是在传输层及传输层以下使用的套接字。

原始套接字在接收和发送时不仅能操作数据部分(TCP Payload / UDP Payload),也能对 IP 首部或TCP 首部和 UDP 首部进行操作。

因此如果我们开发的是更底层的应用,比如发送一个自定义的 IP 包、UDP 包、TCP 包或 ICMP 包,捕获所有经过本机网卡的数据包(sniffer),伪装本机的 IP ,拒绝服务攻击(DOS)等,都可以通过原始套接字(SOCK_RAW)实现。

注意:必须在管理员权限下才能使用原始套接字。

3 Socket() 函数 介绍

3.1 功能

分配文件描述符,创建 socket,即创建网络上进程通信的端点。

3.2 头文件

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

3.3 函数原型

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

3.4 参数

注意:type 和 protocol 不可以随意组合,如 SOCK_STREAM 不可以跟 IPPROTO_UDP 组合。

具体的组合和应用场景可以参考 4 创建 Socket 及其应用场景

3.4.1 domain

domain:即协议域,又称为协议族(family),如下所示:

  • AF_INET / PF_INET(2):IPv4,获取 网络层的数据

  • AF_INET6:IPv6

  • AF_UNIX:UNIX 系统本地通信

  • AF_PACKET / PF_PACKET(17):以太网包,获取 数据链路层的数据

注:

  1. AF = Address Family(地址族),PF = Protocol Family(协议族)

  2. 理论上建立 socket 时是指定协议,应该用 PF_xxxx,设置地址时应该用 AF_xxxx。当然 AF_xxxx和 PF_xxxx 的值是相同的,混用也不会有太大的问题。

3.4.2 type

type:指定 socket 类型,如下所示:

  • SOCK_STREAM(1):面向连接的流式套接字(TCP)

  • SOCK_DGRAM(2):面向无连接的数据包套接字(UDP)

  • SOCK_RAW(3):接收 底层数据报文 的原始套接字

  • SOCK_PACKET(10):过时类型,可以使用,但是已经废弃,以后不保证还能支持,不推荐使用。

3.4.3 protocol

protocol:指定协议,如下所示:

  • 0:自动选择 type 类型对应的默认协议。

  • IPPROTO_IP(0):接受 TCP 类型的数据帧

  • IPPROTO_ICMP(1):接受 ICMP 类型的数据帧

  • IPPROTO_IGMP(2)接受 IGMP 类型的数据帧

  • IPPROTO_TCP(6):接受 TCP 类型的数据帧

  • IPPROTO_UDP(17):接受 UDP 类型的数据帧

  • ETH_P_IP(0x800):接收发往本机 MAC 的 IP 类型的数据帧

  • ETH_P_ARP(0x806):接受发往本机 MAC 的 ARP 类型的数据帧

  • ETH_P_RARP(0x8035):接受发往本机 MAC 的 RARP 类型的数据帧

  • ETH_P_ALL(0x3):接收发往本机 MAC 的所有类型 IP ARP RARP 的数据帧,接收从本机发出的所有类型的数据帧。(混杂模式打开的情况下,会接收到非发往本地 MAC 的数据帧)

3.5 返回值

  • 成功:返回一个文件描述符

  • 失败:返回 -1,并设置 errno

3.6 备注

详情查看 man 手册:man 2 socket

4 创建 Socket 及其应用场景

5 bind() 函数

5.1 功能

将 IP 地址信息绑定到 socket。

5.2 头文件

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

5.3 函数原型

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

5.4 参数

5.4.1 sockfd

通信 socket

5.4.2 addr

要绑定的地址信息(包括IP地址,端口号)。

通用地址结构体定义:

struct sockaddr
{
sa_family_t sa_family; // 地址族, AF_xxx
char sa_data[14]; // 包括 IP 和端口号
}

新型的地址结构体定义:(查看新型的结构体信息: gedit /usr/include/linux/in.h )

struct sockaddr_in
{
__kernel_sa_family_t sin_family; // 地址族,IP 协议。默认:AF_INET
__be16 sin_port; // 端口号
struct in_addr sin_addr; // 网络 IP 地址 unsigned char __pad // 8 位的预留接口
};

5.4.3 addrlen

地址信息大小

5.5 返回值

  • 成功:返回 0

  • 失败:返回 -1,并设置 errno

5.6 备注

详细查看 man 手册:man 2 bind

6 listen() 函数

6.1 功能

监听指定端口,socket() 创建的 socket 是主动的,调用 listen 使得该 socket 成为 监听 socket ,变主动为被动。

6.2 头文件

#include <sys/socket.h>

6.3 函数原型

int listen(int sockfd, int backlog);

6.4 参数

6.4.1 sockfd

通信 socket

6.4.2 backlog

同时能处理的最大连接要求

6.5 返回值

  • 成功:返回 0

  • 失败:返回 -1,并设置 errno

6.6 备注

详细查看 man 手册:man 2 listen

7 accept() 函数

7.1 功能

提取出 监听 socket 的等待连接队列中 第一个连接请求,创建 一个新的 socket,即 连接 socket

新建立的 连接 socket 用于发送数据和接受数据。

7.2 头文件

#include <sys/socket.h>

7.3 函数原型

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

7.4 参数

7.4.1 sockfd

监听 socket,即 在 调用 listen() 后的 监听 socket。

7.4.2 addr

(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。

7.4.3 addrlen

(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。

7.5 返回值

  • 成功:指向 新的 socket(连接 socket)的文件描述符。

  • 失败:返回 -1,并设置 errno

7.6 备注

详细查看 man 手册:man 2 listen

8 connect() 函数

8.1 功能

发送连接请求

8.2 头文件

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

8.3 函数原型

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

8.4 参数

8.4.1 sockfd

通信 socket

8.4.2 addr

要连接的服务器地址

8.4.3 addrlen

地址信息大小

8.5 返回值

  • 成功:返回 0

  • 失败:返回 -1,并设置 errno

8.6 备注

详细查看 man 手册:man 2 connect

9 sendto() 函数

9.1 功能

将数据由指定的 socket 传给对方主机

9.2 头文件

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

9.3 函数原型

int sendto (int sockfd , const void * msg, int len, unsigned int flags, const
struct sockaddr * to , int tolen);

9.4 参数

9.4.1 sockfd

已建立连接的 socket,如果利用 UDP 协议则不需建立连接。

9.4.2 msg

发送数据的缓冲区。

9.4.3 len

缓冲区长度。

9.4.4 flags

调用方式标志位,一般设为 0 。

9.4.5 to

用来指定要传送的网络地址,结构 sockaddr

9.4.6 tolen

sockaddr 的长度

9.5 返回值

  • 成功:返回实际传送出去的字符数

  • 失败:返回 -1,并设置 errno

9.6 备注

详细查看 man 手册:man 2 sendto

10 recvfrom() 函数

10.1 功能

接收远程主机经指定的 socket 传来的数据,并把数据传到由参数 buf 指向的内存空间。

10.2 头文件

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

10.3 函数原型

int recvfrom(int sockfd,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);

10.4 参数

10.4.1 sockfd

已建立连接的 socket,如果利用 UDP 协议则不需建立连接。

10.4.2 buf

接收数据缓冲区。

10.4.3 len

缓冲区长度。

10.4.4 flags

调用方式标志位,一般设为 0 。

10.4.5 from

(可选)指针,指向装有源地址的缓冲区,结构 sockaddr

10.4.6 fromlen

(可选)指针,指向 from 缓冲区长度值,sockaddr 的结构长度

10.5 返回值

  • 成功:返回实际接受到的字符数

  • 失败:返回 -1,并设置 errno

10.6 备注

详细查看 man 手册:man 2 recvfrom

11 字节序

字节序,是 大于一个字节类型的数据在内存中的存放顺序,由 CPU 架构决定,与操作系统无关。是在跨平台和网络编程中,时常要考虑的问题。

11.1 高低地址

在内存中,栈是向下生长的,以char arr[4]为例,(因为 char 类型数据只有一个字节,不存在字节序的问题)依次输出每个元素的地址,可以发现,arr[0] 的地址最低,arr[3] 的地址最高,如图:

11.2 高低字节

在十进制中靠左边的是高位,靠右边的是低位,在其他进制也是如此。

例如: 0x12345678,从高位到低位的字节依次是 0x12、0x34、0x56 和 0x78。

11.3 字节序分类 - 大小端模式

字节序被分为两类:

  1. 大端模式(Big-endian):内存的 低地址 存放 数据的高字节,内存的 高地址 存放 数据的低字节。(与人类阅读顺序一致)

  2. 小端模式(Little-endian),是指内存的 低地址 存放 数据的低字节,内存的 高地址 存放 数据的高字节

大端模式 CPU 代表是 IBM Power PC,小端模式 CPU 代表是 Intel X86、ARM。

11.4 大小端示例

以 0x12345678 为例,两种模式在内存中的存储情况,如下表所示:

11.5 判断大小端

利用 C 语言 union 联合体所有成员共用同一块内存的特性,可以用联合体快速实现判断大小端。

#include <stdio.h>
union u
{
char c[4];
int i;
};
int main(void)
{
union u test;
int j; test.i = 0x12345678; for(j = 0; j < sizeof(test.c); j++)
{
printf("0x%x\n",test.c[j]);
} return 0;
}

运行后结果:

可以看出,我的机器是小端字节序。

11.6 网络字节序与本机字节序

网络字节序(NBO,Network Byte Order),是 TCP/IP 中规定好的一种数据表示格式。它与具体的 CPU 类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。

网络字节序采用大端(Big-endian)字节序排序方式。

主机字节顺序(HBO,Host Network Order),与机器 CPU 相关,数据的存储顺序由 CPU 决定。

11.6.1 转换函数

socket 编程中经常会用到 4 个网络字节顺序与本地字节顺序之间的转换函数:htons()、ntohl()、 ntohs()、htons()。

htonl()--"Host to Network Long"        // 长整型数据主机字节顺序转网络字节顺序
ntohl()--"Network to Host Long" // 长整型数据网络字节顺序转主机字节顺序
htons()--"Host to Network Short" // 短整型数据主机字节顺序转网络字节顺序
ntohs()--"Network to Host Short" // 短整型数据网络字节顺序转主机字节顺序

在使用小端字节序的系统中,这些函数会把字节序进行转换。

在使用大端字节序的系统中,这些函数会定义成空宏。

12 代码示例

12.1 标准套接字(SOCK_STREAM - TCP)

12.1.1 TCP Socket 通信过程

12.1.1.1 服务器

1. 建立连接阶段

  • 调用 socket(),分配文件描述符,创建 服务器 socket

  • 调用 bind(),将 socket 与本地 IP 地址和端口绑定

  • 调用 listen(),监听指定端口,socket() 创建的 socket 是主动的,调用 listen 使得该 socket 成为监听 socket ,变主动为被动

  • 调用 accept(),获得 连接 socket,阻塞等待客户端发起连接

2. 数据交互阶段

  • 调用 read(),阻塞等待客户端发送的数据请求,收到请求后从 read() 返回,处理客户端请求

  • 调用 write(),将数据发送给客户端

3. 关闭连接

  • 当 read() 返回 0 的时候,说明客户端发来了 FIN 数据包,即关闭连接,调用 close() 关闭 连接 socket 和 监听 socket

12.1.1.2 客户端

1. 建立连接阶段

  • 调用 socket(),分配文件描述符,创建 客户端 socket

  • 调用 connect(),向服务器发送建立连接请求

2. 数据交互阶段

  • 调用 write(),向服务器发送数据

  • 调用 read(),阻塞等待服务器应答

3. 关闭连接

  • 当没有数据发送的时候,调用 close() 关闭 客户端 socket ,即关闭连接,向服务器发送 FIN 数据报

12.1.2 单个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子1

12.1.3 多线程实现 - 单个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子2

12.1.4 多路复用实现 - 单个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子3

12.1.5 多个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子4

12.1.6 多线程实现 - 多个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子5

12.1.7 多路复用实现 - 多个客户端单个服务器的 TCP 通信

Linux-C TCP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144 - 例子6

12.2 标准套接字(SOCK_DGRAM- UDP)

12.2.1 UDP Socket 通信过程

12.2.1.1 服务器

  1. 建立连接阶段
  • 调用 socket(),分配文件描述符,创建 服务器 socket

  • 调用 bind(),将 socket 与本地 IP 地址和端口绑定

  1. 数据交互阶段
  • 调用 recvfrom(),阻塞,接受客户端的数据

  • 调用 sendto(),将数据发送给客户端

  1. 关闭连接
  • 调用 close() 关闭 服务器 socket

12.2.1.2 客户端

  1. 建立连接阶段
  • 调用 socket(),分配文件描述符,创建 客户端 socket
  1. 数据交互阶段
  • 调用 sendto(),向服务器发送数据

  • 调用 recvfrom(),阻塞,接受服务器的数据

  1. 关闭连接
  • 调用 close() 关闭 客户端 socket ,即关闭连接。

12.2.2 单个客户端单个服务器的 UDP 通信

代码来源:Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233 - 例子1

12.2.3 多线程实现 - 单个客户端单个服务器的 UDP 通信

代码来源:Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233 - 例子2

12.2.4 多路复用实现 - 单个客户端单个服务器的 UDP 通信

代码来源:Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233 - 例子3

12.2.4 UDP 通信组播

代码来源:Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233 - 例子4

12.2.4 UDP 通信广播

代码来源:Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233 - 例子5

12.3 原始套接字

12.3.1 抓取以太网上的所有数据帧

代码来源:GitHub - zhouyingjiu - https://github.com/zouyingjiu/sniffer


/*
* sniffer.c
*
* 功能:
* linux rawSocket 抓取以太网上的所有数据帧
*
* 参数:
* 无
*
* 注意:
* 执行该程序需要 root 权限 sudo ./
*/ #include <stdio.h>
#include <stdlib.h>
#include <string.h> #ifdef __linux__
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <sys/ioctl.h>
#elif __win32__
#include <windows.h> #endif void UnpackARP(char *buff);
void UnpackIP(char *buff);
void UnpackTCP(char *buff);
void UnpackUDP(char *buff);
void UnpackICMP(char *buff);
void UnpackIGMP(char *buff); int main(int argc, char **argv)
{
int sockfd, i;
char buff[2048]; /*
* 监听以太网上的所有数据帧
*/
if(0 > (sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))))
{
perror("socket error!"); exit(-1);
} while(1)
{
memset(buff, 0, 2048); int n = recvfrom(sockfd, buff, 2048, 0, NULL, NULL); printf("%s\n",buff); printf("开始解析数据包============\n"); printf("大小: %d\n", n); struct ethhdr *eth = (struct ethhdr*)buff; char *nextStack = buff + sizeof(struct ethhdr); int protocol = ntohs(eth->h_proto);
switch(protocol)
{
case ETH_P_IP:
UnpackIP(nextStack);
break; case ETH_P_ARP:
UnpackARP(nextStack);
break;
} printf("解析结束=================\n\n");
} return 0;
} void getAddress(long saddr, char *str)
{
sprintf(str, "%d.%d.%d.%d", \
((unsigned char*)&saddr)[0], \
((unsigned char*)&saddr)[1], \
((unsigned char*)&saddr)[2], \
((unsigned char*)&saddr)[3]);
} void UnpackARP(char *buff)
{
printf("ARP数据包\n");
} void UnpackIP(char *buff)
{
struct iphdr *ip = (struct iphdr*)buff;
char *nextStack = buff + sizeof(struct iphdr);
int protocol = ip->protocol;
char data[20]; getAddress(ip->saddr, data);
printf("来源ip %s\n", data); bzero(data, sizeof(data)); getAddress(ip->daddr, data);
printf("目标ip %s\n", data); switch(protocol)
{
case 0x06:
UnpackTCP(nextStack);
break; case 0x17:
UnpackUDP(nextStack);
break; case 0x01:
UnpackICMP(nextStack);
break; case 0x02:
UnpackIGMP(nextStack);
break; default:
printf("unknown protocol\n");
break;
}
} void UnpackTCP(char *buff)
{
struct tcphdr *tcp = (struct tcphdr*)buff; printf("传输层协议:tcp\n"); printf("来源端口:%d\n", ntohs(tcp->source));
printf("目标端口:%d\n", ntohs(tcp->dest));
} void UnpackUDP(char *buff)
{
struct udphdr *udp = (struct udphdr*)buff; printf("传输层协议:udp\n"); printf("来源端口:%d\n", ntohs(udp->source));
printf("目的端口:%d\n", ntohs(udp->dest));
} void UnpackICMP(char *buff)
{
printf("ICMP数据包\n");
} void UnpackIGMP(char *buff)
{
printf("IGMP数据包\n");
}

12.3.2 抓取以太网上的所有数据帧,匹配 HTTP 协议并发送 TCP RST

代码来源:我的 Github - https://github.com/PikapBai/sniffer_cmpHTTP_sendTCP

13 参考资料

  1. 套接字 - 百度百科 - https://baike.baidu.com/item/套接字/9637606?fromtitle=socket&fromid=281150&fr=aladdin

  2. RAW SOCKET - 百度百科 - https://baike.baidu.com/item/RAW SOCKET/995623?fromtitle=原始套接字&fromid=23692610&fr=aladdin#ref_[1]_4263346

  3. 原始套接字简介 - chengqiuming - https://blog.csdn.net/chengqiuming/article/details/89577351

  4. 原始套接字概述 - anton_99 - https://blog.csdn.net/anton_99/article/details/95646879?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

  5. Linux 原始套接字抓取底层报文 - 2603898260 - https://blog.csdn.net/s2603898260/article/details/85020006?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

  6. Linux-C TCP 简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540144

  7. 【Linux网络编程】socket编程“网络字节顺序”和“主机字节顺序” - qq_20553613 - https://blog.csdn.net/qq_20553613/article/details/86385271

  8. 网络字节序 - 百度百科 - https://baike.baidu.com/item/网络字节序/12610557?fr=aladdin

  9. 字节序(大小端)理解 - sunflower_della - https://blog.csdn.net/sunflower_della/article/details/90439935

  10. 理解大小端字节序 - fan-yuan - https://www.cnblogs.com/fan-yuan/p/10406315.html

  11. linux网络编程之TCP/IP的TCP socket通信过程(含实例代码) - 知乎 - linux服务器开发专栏 - https://zhuanlan.zhihu.com/p/148739946

  12. Linux C Socket UDP编程详解及实例分享 - 知乎 - linux服务器开发专栏 - https://zhuanlan.zhihu.com/p/131402832

  13. Linux-C UDP简单例子 - nanfeibuyi - https://blog.csdn.net/nanfeibuyi/article/details/88540233

  14. 《图解 TCP/IP》(第 5 版)[日]竹下隆史 /[日]村山公保/ [日]荒井透 / [日]苅田幸雄

  15. 浅谈linux下原始套接字 SOCK_RAW 的内幕及其应用 - 知乎 - linux服务器开发专栏 - https://zhuanlan.zhihu.com/p/254912774

  16. GitHub - zhouyingjiu - https://github.com/zouyingjiu/sniffer

Linux C Socket 编程的更多相关文章

  1. LInux下socket编程学习笔记

    1.socket套接字: socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模 ...

  2. Linux下Socket编程的端口问题( Bind error: Address already in use )

    Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...

  3. linux下socket编程实例

    linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...

  4. Linux的SOCKET编程详解(转)

    Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系 ...

  5. 【ARM-Linux开发】Linux的SOCKET编程详解

    Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系 ...

  6. Linux下socket编程基本知识

    本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linu ...

  7. linux下socket编程

    相关结构 //下边这两个结构定义在<sys/types.h>里 //一般的地址结构,只能用于覆盖(把其他地址转换为此类型),且只能引用该地址的sa_family字段 struct sock ...

  8. [转] - linux下socket编程实例

    一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.socket也有一个类似于打开文件 ...

  9. Linux的SOCKET编程详解

    1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如 U ...

  10. linux多线程socket编程一些心得

    http://hi.baidu.com/netpet/blog/item/2cc79216d9012b54f2de32b9.html 前段时间将新的web模型办到linux上来,用epoll代替了IO ...

随机推荐

  1. java 反射之静态and动态代理

    首先说一下我们什么情况下使用代理? (1)设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the c ...

  2. 【dos】wmic命令

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 磁盘 查看硬盘信息:wmic diskdrive 查看逻辑盘信息:wmic l ...

  3. 关于.netMVC 出现@ViewBag 出现错误(波浪红线)的解决方法

    解决vs2015.vs2013解决mvc5 viewbag问题 1.关闭vs2015或者vs2013 打开我的电脑或者文件夹 2.打开我的电脑 在地址栏输入 %UserProfile%\AppData ...

  4. Java中字符串相关操作(判断,增删,转换)

    1:判断字符串中是否包含某个字符(字符串): startsWith(): 这个方法有两个变体并测试如果一个字符串开头的指定索引指定的前缀或在默认情况下从字符串开始位置 此方法定义的语法如下: publ ...

  5. Ubuntu20.04 体验和美化

    Ubuntu20.04美化和体验 windows用久了,换下系统也挺好的.ubuntu20.04优化后,用起来蛮舒服的. 系统配置 1.修改软件源 Ubuntu默认是国外的软件源, 我们可以手动切换为 ...

  6. centos8平台:用fontconfig安装及管理字体(fc-list/fc-match/fc-cache)

    一,fc-list所属的rpm包 [root@blog ~]$ whereis fc-list fc-list: /usr/bin/fc-list /usr/share/man/man1/fc-lis ...

  7. docker19.03限制容器使用的cpu资源

    一,用--cpus限制可用的cpu个数 例子: [root@localhost liuhongdi]# docker run -idt --name kafka1 --hostname kafka1 ...

  8. 浏览器页面左上角出现undefined

    浏览器页面左上角出现undefined, js文档中: let list; list += html代码; 解决办法: let list = html代码;

  9. 如何高效定义和验证restful请求的参数

    go-zero针对文本的序列化和反序列化主要在三个地方使用 http api请求体的反序列化 http api返回体的序列化 配置文件的反序列化 完整示例可参照下面这篇文章: 快速构建高并发微服务 1 ...

  10. CPU 底层运算之乘法运算

    CPU 运算加减法运算 假设计算  3+3  原码是0011 * 0011(以4位存贮单元,因为是原码,最高位不代表符号位) 1. 首先 判断 两个加数是否有 负数(减法)  如果有 负数 先将负数转 ...