前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux下Socket编程入门

Linux下Socket编程入门

原创
作者头像
_咯噔_
修改于 2022-04-27 06:50:23
修改于 2022-04-27 06:50:23
3.7K00
代码可运行
举报
文章被收录于专栏:CS学习笔记CS学习笔记
运行总次数:0
代码可运行

1、网络字节序和主机字节序

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

不同的CPU有不同的字节序类型,这些字节序是指 整数 在内存中保存的顺序,这个叫做主机字节序,有大端小端两种。

htons()--"Host to Network Short"

htonl()--"Host to Network Long"

ntohs()--"Network to Host Short"

ntohl()--"Network to Host Long"

2、几个结构体

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct sockaddr {

  unsigned short sa_family; /* 地址家族, AF_xxx */

  char sa_data[14]; /*14字节协议地址*/

};
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct sockaddr_in {

  short int sin_family; /* 通信类型 */

  unsigned short int sin_port; /* 端口 */

  struct in_addr sin_addr; /* Internet 地址 */

  unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/

};
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct in_addr {

  unsigned long s_addr;

};

3、inet_addr和inet_ntoa

函数inet_addr(),将IP地址从字符串转换成无符号长整型,注意,inet_addr()返回的地址已经是网络字节格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ina.sin_addr.s_addr = inet_addr("132.241.5.10");

inet_ntoa()将结构体in-addr作为一个参数,不是长整形。同样需要注意的是它返回的是一个指向一个字符的指针

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
printf("%s",inet_ntoa(ina.sin_addr));

4、socket()函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int socket(int domain, int type, int protocol);

domain:即协议域,又称为协议族(family)。常用的协议族有AF_INET

type:指定socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等等(socket的类型有哪些?)。

protocol:故名思意,就是指定协议。当protocol为0时,会自动选择type类型对应的默认协议。

5、bind()函数

绑定套接字到指定的IP地址和端口号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

6、connect()

serv_addr 是保存着目的地端口和IP地址的数据结构 struct sockaddr

至于客户端,内核将自动选择一个合适的端口号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

7、listen()

bind()之后用listen,监听绑定的端口号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int listen(int sockfd, int backlog);

使用两个队列实现,一个SYN队列(或半连接队列)和一个accept队列(或完整的连接队列)。 处于SYN RECEIVED状态的连接被添加到SYN队列,并且当它们的状态改变为ESTABLISHED时,即当接收到3次握手中的ACK分组时,将它们移动到accept队列。 显而易见,accept系统调用只是简单地从完成队列中取出连接。 在这种情况下,listen syscall的backlog参数表示完成队列的大小

8、accept()函数

accept()函数实际做的是在已完成连接队列列头返回下一个已完成连接,服务器三路握手在listen()函数之后,accept()之前, 由内核来自动完成了三路握手。

函数通过后两个参数返回客户端的sockaddr_in结构体和长度

返回值是一个新的套接字文件描述符,这样就有两个套接字了,原来的一个还在侦听你的那个端口, 新的在准备发送 (send()) 和接收 ( recv()) 数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int accept(int sockfd, void *addr, int *addrlen);

9、send()和recv()函数

这两个函数用于流式套接字或者数据报套接字的通讯。flag一般为0。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int send(int sockfd, const void *msg, int len, int flags);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int recv(int sockfd, void *buf, int len, unsigned int flags);

如果你用 connect() 连接一个数据报套接字,你可以简单的调用 send() 和 recv() 来满足你的要求

10、sendto() 和 recvfrom()函数

数据报套接字使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int sendto(int sockfd, const void *msg, int len, unsigned int flags, 

const struct sockaddr *to, int tolen);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int recvfrom(int sockfd, void *buf, int len, unsigned int flags,  

struct sockaddr *from, int *fromlen);

11、getpeername()函数

函数 getpeername() 告诉你在连接的流式套接字上谁在另外一边

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);

12、gethostname()函数

返回你程序所运行的机器的主机名字

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int gethostname(char *hostname, size_t size);

13、gethostbyname()函数

多用于客户端。DNS域名服务

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct hostent *gethostbyname(const char *name);
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct hostent {

  char *h_name;

  char **h_aliases;

  int h_addrtype;

  int h_length;

  char **h_addr_list;

};  

14、TCP的例子

服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define MYPORT 3490 /*定义用户连接端口*/

#define BACKLOG 10 /*多少等待连接控制*/

main()

{

  int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */

  struct sockaddr_in my_addr; /* my address information */

  struct sockaddr_in their_addr; /* connector's address information */

  int sin_size;

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

  perror("socket");

  exit(1);

  }

  my_addr.sin_family = AF_INET; /* host byte order */

  my_addr.sin_port = htons(MYPORT); /* short, network byte order */

  my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */

  bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */

 

  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1) {

  perror("bind");

  exit(1);

  }

  if (listen(sockfd, BACKLOG) == -1) {

  perror("listen");

  exit(1);

  }

 

  while(1) { /* main accept() loop */

  sin_size = sizeof(struct sockaddr_in);

  if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {

  perror("accept");

  continue;

  }

  printf("server: got connection from %s\n", \

  inet_ntoa(their_addr.sin_addr));

  if (!fork()) { /* this is the child process */

  if (send(new_fd, "Hello, world!\n", 14, 0) == -1)

  perror("send");

  close(new_fd);

  exit(0);

  }

  close(new_fd); /* parent doesn't need this */

  while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */

}

}

客户端:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define PORT 3490 /* 客户机连接远程主机的端口 */

#define MAXDATASIZE 100 /* 每次可以接收的最大字节 */

int main(int argc, char *argv[])

{

int sockfd, numbytes;

char buf[MAXDATASIZE];

struct hostent *he;

struct sockaddr_in their_addr; /* connector's address information */

if (argc != 2) {

fprintf(stderr,"usage: client hostname\n");

exit(1);

}

if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */

herror("gethostbyname");

exit(1);

}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

perror("socket");

exit(1);

}

their_addr.sin_family = AF_INET; /* host byte order */

their_addr.sin_port = htons(PORT); /* short, network byte order */

their_addr.sin_addr = *((struct in_addr *)he->h_addr);

bzero(&(their_addr.sin_zero),; /* zero the rest of the struct */

if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) {

perror("connect");

exit(1);

}

if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {

perror("recv");

exit(1);

}

buf[numbytes] = '\0';

printf("Received: %s",buf);

close(sockfd);

return 0;

}

15、UDP的例子

服务器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define MYPORT 4950 /* the port users will be sending to */

#define MAXBUFLEN 100

main()

{

int sockfd;

struct sockaddr_in my_addr; /* my address information */

struct sockaddr_in their_addr; /* connector's address information */

int addr_len, numbytes;

char buf[MAXBUFLEN];

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {

perror("socket");

exit(1);

}

my_addr.sin_family = AF_INET; /* host byte order */

my_addr.sin_port = htons(MYPORT); /* short, network byte order */

my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */

bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {

perror("bind");

exit(1);

}

addr_len = sizeof(struct sockaddr);

if ((numbytes=recvfrom(sockfd, buf, MAXBUFLEN, 0,     \

(struct sockaddr *)&their_addr, &addr_len)) == -1) {

perror("recvfrom");

exit(1);

}

printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));

printf("packet is %d bytes long\n",numbytes);

buf[numbytes] = '\0';

printf("packet contains \"%s\"\n",buf);

close(sockfd);

}

客户端:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define MYPORT 4950 /* the port users will be sending to */

int main(int argc, char *argv[])

{

int sockfd;

struct sockaddr_in their_addr; /* connector's address information */

struct hostent *he;

int numbytes;

 

if (argc != 3) {

fprintf(stderr,"usage: talker hostname message\n");

exit(1);

}

 

if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */

herror("gethostbyname");

exit(1);

}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {

perror("socket");

exit(1);

}

their_addr.sin_family = AF_INET; /* host byte order */

their_addr.sin_port = htons(MYPORT); /* short, network byte order */

their_addr.sin_addr = *((struct in_addr *)he->h_addr);

bzero(&(their_addr.sin_zero),; /* zero the rest of the struct */

if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, \

(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {

perror("sendto");

exit(1);

}

printf("sent %d bytes to %s\n",numbytes,inet_ntoa(their_addr.sin_addr));

close(sockfd);

return 0;

}

16、阻塞

很多函数都利用阻塞。accept() 阻塞,所有的 recv*() 函数阻塞。它们之所以能这样做是因为它们被允许这样做。当你第一次调用 socket() 建立套接字描述符的时候,内核就将它设置为阻塞,如果你不想套接字阻塞, 你就要调用函数 fcntl():

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
#include <fontl.h>
……
sockfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
……

让你的程序在忙等状态查询套接字的数据,这将浪费大量的 CPU 时间。更好的解决之道是用下面讲的 select() 去查询是否有数据要读进来。

17、select()--多路复用 I/O

select() 让你可以同时监视多个套接字。如果你想知道的话,那么它就会告诉你哪个套接字准备读,哪个又准备写,哪个套接字又发生了例外 (exception)。

如果你有一个正在侦听 (listen()) 的套 接字,你可以通过将该套接字的文件描述符加入到 readfds 集合中来看是否有新的连接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

int select(int numfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

numfds是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1

fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄。fd_set集合可以通过一些宏由人为来操作。下面有一些宏来对这个类型进行操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FD_ZERO(fd_set *set) – 清除一个文件描述符集合
FD_SET(int fd, fd_set *set) - 添加fd到集合
FD_CLR(int fd, fd_set *set) – 从集合中移去fd
FD_ISSET(int fd, fd_set *set) – 测试fd是否在集合中

struct timeval用来代表时间值,有两个成员,一个是秒数,另一个是微秒数。 若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回。

I/O multiplexing
I/O multiplexing

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
Linux 网络编程:从 Socket API 到极简 Redis 发布/订阅 sub/pub 服务的实现
本文旨在系统性地阐述 Linux 环境下的网络编程基础,重点关注 Socket 应用程序接口(API)的原理与应用。通过循序渐进的方式,结合具体的 C 语言代码示例,我们将剖析核心系统调用的机制,并最终构建一个基于传输控制协议(TCP)的简化版发布/订阅(Publish/Subscribe, Pub/Sub)服务器模型。
Piper破壳
2025/05/07
460
【TCP服务器的演变过程】编写第一个TCP服务器:实现一对一的连接通信
在构建网络应用时,常常会接触到各种网络协议,其中TCP(Transmission Control Protocol)作为一种面向连接、可靠的传输层协议,扮演着至关重要的角色。理解TCP协议及其在服务器开发中的应用,是每一位网络编程初学者的必经之路。
Lion 莱恩呀
2025/05/13
810
【TCP服务器的演变过程】编写第一个TCP服务器:实现一对一的连接通信
socket网络编程(六)——心跳包问题
问大家一个问题,如果客户端和服务端长时间没有相互发送数据的话,那么我们怎么来判断这个连接是否存在的呢?有些人可能很自然地说直接send一下不就可以了,确实可以这样进行判断,那么我们发送的时候可以选择发送任何东西,所以一般都是发送一个空包,这个就是心跳包。
一点sir
2024/01/10
4670
一个简单的Linux下Client/Server应答例子
题目:Hello world 要求:案例程序基于TCP协议,由客户程序启动后向服务器程序发送“hello world”,服务器程序显示客户机IP地址、端口、以及发送的信息。服务器将收到的字符串发送给客户端,客户端显示验证。 使用方法:在linux下编译 $gcc -o client client.c $gcc -o server server.c 先运行server程序$./server 再运行client程序$./client xxx(你要访问服务器名---非IP)
阳光岛主
2019/02/19
1.3K0
socket网络编程(五)——粘包拆包问题
假设一个这样的场景,客户端要利用send()函数发送字符“asd”到服务端,连续发送3次,但是服务端休眠10秒之后再去缓冲池中接收。那么请问10秒之后服务端从缓冲区接收到的信息是“asd”还是“asdasdasd”呢?如果大家有去做实验的话,可以知道服务端收到的是“asdasdasd”,为什么会这样呢?按正常的话,服务端收到的应该是“asd”,剩下的两个asd要不就是收不到要不就是下次循环收到,怎么会一次性收到“asdasdasd”呢?如果要说罪魁祸首的话就是那个休眠10秒,导致数据粘包了!
一点sir
2024/01/10
3430
socket网络编程(五)——粘包拆包问题
Tcp协议Socket编程
  本次socket编程需要使用到 日志文件,此为具体日志编写过程。以及 线程池,线程池原理比较简单,看注释即可。
用户11029129
2024/11/22
720
Tcp协议Socket编程
浅谈I/O模型
作为程序员,在日常工作中,都或多或少的接触过网络I/O这个概念,接触过网络编程,听说过socket等等,但是对于更深层次的理解,多少还是有点欠缺,通过本文,可以了解网络中最重要的模块I/O,以及对几种网络模型的介绍,在我们日常工作开发过程中,可以针对特定需求,选择特定的网络模型,达到事半功倍的效果。
高性能架构探索
2021/04/13
6270
Linux网络编程一步一步学-异步通讯聊天程序select
/************关于本文档********************************************
阳光岛主
2019/02/19
8230
【Linux网络编程】Socket编程--TCP:echo server | 多线程远程命令执行
在学习本章之前,先看【Linux网络编程】Socket编程–UDP:实现服务器接收客服端的消息 | DictServer简单的英译汉的网络字典 | 简单聊天室】,里面详细介绍函数的使用方法,小编在这篇文章不再具体介绍。
南桥
2024/11/14
1620
【Linux网络编程】Socket编程--TCP:echo server | 多线程远程命令执行
C语言实现Socket简单通信
https://www.cnblogs.com/Dukefish/p/9197830.html
C语言中文社区
2022/05/30
6750
select的限制以及poll的使用
1.先说select在多路IO中的限制: 1)linux中每个程序能够打开的最多文件描述符是有限制的。默认是1024. 可以通过ulimit -n进行查看和修改:
xcywt
2022/05/09
1K0
select的限制以及poll的使用
【Linux网络编程】Socket编程--UDP:实现服务器接收客服端的消息
<font color= black face="楷体" size=3><center>🌈个人主页:南桥几晴秋
南桥
2024/10/24
1850
【Linux网络编程】Socket编程--UDP:实现服务器接收客服端的消息
百问FB网络编程 - 主要函数介绍
domain是网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等)。
阿志小管家
2024/12/05
840
TCP网络编程中connect()、listen()和accept()三者之间的关系 ( 非常重要!!)
基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下:
战神伽罗
2019/09/04
2.9K0
TCP网络编程中connect()、listen()和accept()三者之间的关系 ( 非常重要!!)
Socket编程回顾,一个最简单服务器程序
第一次接触服务器是快毕业的时候,是不是有点晚(# ̄ω ̄),这也导致工作方向一直没考虑网络编程这块,做了好多其他没啥“意思”的技术。 之前看到一篇博文提到程序猿80%都是庸才,10%是人才,10%是天才,深有感触。仔细想想自己是不是也是还在那80%里面挣扎?一个抱怨这抱怨那的trouble maker,写着烂的掉渣的代码,永远在别人身后不思进取,给剩下的20%的同事埋雷。 扯远了,重新回顾Socket,温习下Linux内核是怎么处理Socket的吧。 文件描述符,在网络编程中经常提及这个词,当时初
Aichen
2018/05/18
4760
提升性能的必备技术:Linux网络IO与select详解
IO 即“Input”和“Output”的组合,即输入/输出,IO用来处理设备之间的数据传输。socket/fd也是一种IO。
Lion 莱恩呀
2024/08/10
1760
提升性能的必备技术:Linux网络IO与select详解
c语言socket通信
1. 前 言 网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。
全栈程序员站长
2022/09/14
1.3K0
linux网络编程系列(三)--tcp和udp的基本函数调用过程及如何选择
TCP是TCP/IP体系中面向连接的传输层协议,它提供全双工和可靠交付的服务。它采用许多机制来确保端到端结点之间的可靠数据传输,如采用序列号、确认重传、滑动窗口等。
cpp加油站
2021/04/16
1K0
linux网络编程系列(三)--tcp和udp的基本函数调用过程及如何选择
Linux下select的用法--实现一个简单的回射服务器程序
2. 函数说明:可以同时监控多个文件描述符是否发生了读写或者异常。(有点像windows下的waitformultipleobjects,可以同时等待多个事件) 参数说明: 1)nfds:要监控的文件描述符的最大值加1,这个值不能错。 2)readfds:指向fd_set的指针。这是一个集合,专门用于监视读取数据的。所有需要监控读取数据的描述符都需要放进这个集合中。比如你需要监控4描述符的读取数据,就把4放进这个集合之中。 3)writefds:同上,这里是专门监视写的集合 4)exceptfds:同上,这里是专门监视异常的集合 5)timeout:超时。指向的timeval 结构体。 如果参数设为NULL,则select是阻塞的。 如果不为空,则表示超时时间(当结构体里面的成员都设为0时,表示不阻塞,立即返回)。
xcywt
2022/05/09
6760
加密通讯协议SSL编程周立发
编译程序用下列命令: gcc -Wall ssl-client.c -o client gcc -Wall ssl-server.c -o server 运行程序用如下命令: ./server 7838 1 127.0.0.1 cacert.pem privkey.pem ./client 127.0.0.1 7838 用下面这两个命令产生上述cacert.pem和privkey.pem文件: openssl genrsa -out privkey.pem 2048 openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 具体请参考 “OpenSSL体系下使用密钥数字证书等” 如果想对SSL有更深入的了解,请学习计算机安全相关的内容,尤其是非对称加密技术。 如果想对SSL库的源代码有深入学习,请去 www.openssl.org 下载源码来阅读。
一见
2018/08/07
1.4K0
相关推荐
Linux 网络编程:从 Socket API 到极简 Redis 发布/订阅 sub/pub 服务的实现
更多 >
目录
  • 1、网络字节序和主机字节序
  • 2、几个结构体
  • 3、inet_addr和inet_ntoa
  • 4、socket()函数
  • 5、bind()函数
  • 6、connect()
  • 7、listen()
  • 8、accept()函数
  • 9、send()和recv()函数
  • 10、sendto() 和 recvfrom()函数
  • 11、getpeername()函数
  • 12、gethostname()函数
  • 13、gethostbyname()函数
  • 14、TCP的例子
  • 15、UDP的例子
  • 16、阻塞
  • 17、select()--多路复用 I/O
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档