socket套接字编程
一、概述
1、socket是一种进程间通信方式,既可以用于一台机器,也可以用于网络。常用语C/S模型。
2、可以跨越Windows和Linux操作系统,可以跨越不同语言。
3、注意网络字节序和主机字节序的转换;可以不用判断,直接调用函数,函数内部会做出判断。
二、socket()
1、<sys/types.h><sys/socket.h>
2、int socket(int domain,int type,int protocol);
3、domain:创建套接字所使用的协议簇(地址)
AF_UNIX:本机
AF_INET:IPv4
AF_INET6:IPv6
AF:address family
4、type:套接字类型
SOCK_STREAM:流,用于tcp
SOCK_DGRAM:数据报,用于UDP
SOCK_RAW:原始,可以操作ICMP等
5、protocol:协议,Linux下默认为0,即由domain和type可以确定所使用的协议。
6、返回值:成功后,返回套接字;否则,返回-1,错误存入errno。
7、可以理解为:domain是网络层的参数,type是传输层的参数。
三、bind()
1、<sys/types.h><sys/socket.h>
2、int bind(int sockfd,sockaddr* my_addr,socklen_t addlen);
3、作用:将IP地址+端口和socket绑定。一般服务器需要,客户端不需要bind()。但是实际上,对于UDP,客户端在发送时,内核都会自动绑定(将IP地址+端口和socket绑定);对于TCP,个人认为应该不会,因为服务器端通过连接返回,所以客户端不用bind()。
4、sockfd:socket文件描述符;addlen:sockaddr结构的长度。
5、返回值:成功0,失败,返回-1,错误存入errno。
6、struct sockaddr是通用的套接字地址,实际上很少使用,而是使用sockaddr_in。
7、struct sockaddr_in(TCP/IP协议簇常用)
(1)头文件:<netinet/in.h>
(2)定义
struct sockaddr_in{
unsigned short sin_family;//AF_INET(TCP/IP)
unsigned short sin_port;//0-1023特用
struct in_addr sin_addr;//32位IP地址
unsigned char sin_zero[8];//填充
};
struct in_addr{
unsigned long s_addr;//或in_addr_t
};
s_addr可以设置为INADDR_ANY,表示本机上的所有IP(多宿主主机有多个网卡)
四、listen()
1、<sys/types.h><sys/socket.h>
2、int listen(int sockfd,int backlog);
3、功能:一般在服务器端使用。初始化服务器可连接队列,由于是顺序处理连接请求,所有将暂时不能处理的放到等待队列里面,长度由backlog确定。
4、backlog:连接队列的最大长度,一般为20,有时为10或5。
5、返回值:成功0,失败,返回-1,错误存入errno。
6、注意,listen()是非阻塞调用,listen()执行后,套接字处于监听状态,进程处于执行状态,即一个套接字listen()一次即可,直至进程退出才会失效。
五、accept()
1、<sys/types.h><sys/socket.h>
2、int accept(int sockfd,sockaddr *addr,socklen_t *addrlen);
3、功能:当一个客户端的连接请求到达服务器监听接口时,在队列中等待;accept()执行后,返回一个套接字描述表示一个客户端的连接,并用这个套接字进行send()和recv()。
4、返回值:成功后,返回代表连接的套接字(性质与sockfd相同),失败,返回-1,错误存入errno。
5、若sockfd是阻塞的,且连接队列为空,则accept()将被阻塞知道有连接请求为止;若为非阻塞的,且连接队列为空,则accept()返回-1,errno被设置为EAGAIN。
6、注意,accept发生的阶段是三次握手之后,即从连接队列中取出相应连接进行处理。
六、connect()
1、<sys/types.h><sys/socket.h>
2、int connect(int sockfd,sockaddr *addr,socklen_t addrlen);
3、功能:一般在客户端使用。客户端发出连接请求,因为客户端的地址不重要(服务器通过连接返回),因此客户端无需bind()。一个socket只能connect一个主机。
4、返回值:成功0,失败,返回-1,错误存入errno。
七、send()和recv()
1、<sys/types.h><sys/socket.h>
2、函数原型
ssize_t send(int conn_fd,const void *msg,size_t len,int flags);
ssize_t recv(int conn_fd,void *buf,size_t len,int flags);
3、服务器端和客户端都可以send()和recv()。注意,send()只是将数据由msg存入socket的缓冲区里面,具体的发送操作由操作系统完成;同理,recv()是将socket缓冲区里面的数据读到buf中,具体的接收操作也是由操作系统完成的。
4、参数说明
conn_fd:连接好的套接字
msg/buf:发送或接受数据的缓冲区
len:缓冲区长度
flags:控制选项,一般为0。
5、返回值:成功,返回实际发送或接受的字节数,失败,返回-1,错误存入errno。
6、疑问:对于UDP,也是在缓冲区中取出,但是UDP是有边界的呀??todo
7、可以利用recv的返回值以及等待时间,来判断是否停止接受。
八、close()
1、<unistd.h>
2、int close(int fd);
3、关闭一个套接字描述符。
4、返回值:成功0,失败,返回-1,错误存入errno。
九、地址转换
1、<arpa/inet.h>
2、点分十进制字符串转化为unsigned long/in_addr_t
in_addr_t inet_addr(const char* cp);
3、in_addr转化为点分十进制字符串:inet_ntoa();
十、TCP与UDP的差异
1、UDP在connect的时候,不会进行三次握手,甚至不会发送任何数据包;只是发送/接收的时候不再需要指定对方的地址(内核记录了IP地址和端口)。
因此我认为,UDP客户端可以不connect。
2、UDP服务器端不需要listen和accept,可以直接接收;但是有了之后,服务端也记录了客户端的IP地址和端口,每次发送和接收的时候不需要sendto()、recvfrom()。
3、对于服务器端:UDP的服务器端可以不需要绑定,使用sendto和recvfrom,但是TCP的服务器端必须绑定,因为在sendto和recvfrom之前还要listen和accept。
对于客户端:TCP和UDP都不需要bind。TCP因为建立了连接,可以按照连接返回(其实连接还是按IP+端口确定的)。UDP客户端在第一次发送时,内核也会将IP地址和端口与socket绑定。
注意,绑定的含义是将socket与IP地址和端口绑定;无论是否绑定,数据包中肯定是有IP地址和端口的。
4、综合1、2、3可知,UDP的客户端可以新建一个socket后,直接使用sendto发送数据;UDP的服务器端可以新建一个socket后,直接用recvfrom接收数据。
5、区分TCP和UDP的方式:socket的类型是SOCK_STREAM还是SOCK_DGRAM;而不是使用了哪些函数,因为由上述可知,TCP与UDP使用的函数可能相同。
十一、阻塞与非阻塞
1、受影响的函数:connect、accept、send、recv等。
(1)connect(TCP)
非阻塞:connect会立即返回EINPROGRESS错误,表示连接操作正在进行中,但是仍未完成;同时TCP的三路握手操作继续进行;在这之后,我们可以调用select来检查这个链接是否建立成功。
阻塞:线程阻塞,若连接在超时之前建立,则返回0;若超时(一般为75s-几分钟),则返回负数。
(2)accept(TCP):见五、5
(3)send、recv
非阻塞:如果缓冲区有空间或者有内容,立马返回实际放入或取出的字节数,如果没有,立马返回-1。
阻塞:如果有足够空间或者内容,肯定就返回n了;如果完全没有空间或者内容,肯定就返回-1了;但是如果有部分空间或者内容,是等待呢,还是返回??todo
2、阻塞模式效率低,编程简单,适用于小型系统;非阻塞模式效率高,但是编程复杂,适用于大型系统。
3、(貌似)SOCK_STREAM默认是阻塞的,SOCK_DGRAM默认是非阻塞的。
4、fctnl或者select可以转换socket的阻塞属性。
socket套接字编程的更多相关文章
- linux网络环境下socket套接字编程(UDP文件传输)
今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...
- linux网络编程-(socket套接字编程UDP传输)
今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...
- socket套接字编程 HTTP协议
socket套接字编程 套接字介绍 1. 套接字 : 实现网络编程进行数据传输的一种技术手段 2. Python实现套接字编程:import socket 3. 套接字分类 >流式套接 ...
- socket 套接字编程
今日内容 socket 套接字编程 简易服务端与客户端代码实现 通信循环 黏包现象(TCP协议) 报头制作.struct 模块.封装形式 内容详细 一.socket 套接字编程 实现一款能够进行数据交 ...
- Linux之socket套接字编程20160704
介绍套接字之前,我们先看一下传输层的协议TCP与UDP: TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UD ...
- 基于TCP协议的socket套接字编程
目录 一.什么是Scoket 二.套接字发展史及分类 2.1 基于文件类型的套接字家族 2.2 基于网络类型的套接字家族 三.套接字工作流程 3.1 服务端套接字函数 3.2 客户端套接字函数 3.3 ...
- 基于TCP连接的socket套接字编程
基于TCP协议的套接字编程(简单) 服务端 import socket server = socket.socket() server.bind( ('127.0.0.1', 9999) ) serv ...
- day31 socket套接字编程
为什么要有套接字编程? 在上节课的学习中,我们学习了OSI七层协议,但是如果每次进行编程时我们都需要一层一层的将各种协议使用在我们的程序中,这样编写程序实在是太麻烦了,所以为了让程序的编写更加的简单, ...
- socket套接字编程(1)——基本函数
TCP交互流程: 服务器:1. 创建socket:2. 绑定socket和端口号:3. 监听端口号:4. 接收来自客户端的连接请求:5. 从socket中读取字符:6. 关闭socket. 客户端:1 ...
- 19、网络编程 (Socket套接字编程)
网络模型 *A:网络模型 TCP/IP协议中的四层分别是应用层.传输层.网络层和链路层,每层分别负责不同的通信功能,接下来针对这四层进行详细地讲解. 链路层:链路层是用于定义物理传输通道,通常是对某些 ...
随机推荐
- 使用AF_INET实现点对点的通信示例
作者:Younger Liu,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可. 1. 客户端(发送方) 操作流如下: (1) 使用AF_INET协议簇, ...
- macOS 中的 Rootless 机制
一.前因 苹果从 OS X El Capitan 10.11 系统开始使用了 Rootless 机制,可以将该机制理解为一个更高等级的系统的内核保护措施,系统默认将会锁定 /system./sbin. ...
- JS基础——循环很重要
介绍循环之前,首先要说一下同样很重要的if-else结构,switch-case结构 ①if-else结构 if(判断条件) { 条件为true时执行 } else{ 条件为false时执行 } ②i ...
- css优先级之特殊性
在前端开发的时候,css构建样式规则,这个时候我们会遇到一个问题:当我们对同一个元素做多个样式规则,其中发生了冲突的时候,css是如何选择最终呈现的样式 如下: div{ color:red; } d ...
- Github--账号重新申请与配置
2017-04-24 最近洗心革面痛下决心要好好再深入学习一番前端,正好加入了一个外包团队接了份单子,外包项目正在如火如荼地进行着,自己也打算趁这个机会来好好学习总结一番. 但是俗话说得好," ...
- 设置共享目录(主机win7,虚拟机Ubuntu)
1.安装增强功能包 启动虚拟机后,在 设备 -> 分配光驱 选择VBoxGuestAdditions.iso增强包镜像(在virtualbox安装目录下) 在虚拟机中挂载光驱镜像: #mkdir ...
- 【Objective-C 基础】4.分类和协议
1.分类 OC提供了一种与众不同的方式--Category,可以动态的为已经存在的类添加新的行为(方法) 这样可以保证类的原始设计规模较小,功能增加时再逐步扩展. 使用Category对类进行扩展时, ...
- OC语言中如何在便利构造器中利用便利初始化进行初始化
因为利用便利初始化在便利构造器中进行初始化,所以要利用便利初始化的声明及实现部分,可与前篇做比较: 1. 主函数部分: 2. 接口部分: 3. 实现部分: 4. 打印结果: 感兴趣的朋友们可自己与前面 ...
- [笔记]机器学习(Machine Learning) - 03.正则化(Regularization)
欠拟合(Underfitting)与过拟合(Overfitting) 上面两张图分别是回归问题和分类问题的欠拟合和过度拟合的例子.可以看到,如果使用直线(两组图的第一张)来拟合训,并不能很好地适应我们 ...
- Java学习笔记——Linux下安装配置MySQL
山重水复疑无路,柳暗花明又一村 --游山西村 系统:Ubuntu 16.04LTS 1\官网下载mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz2\建立工作组:$su ...