【1】TCP/IP协议分成了两个不同的协议:
用来检测网络传输中差错的传输控制协议TCP
专门负责对不同网络进行互联的互联网协议IP
【2】OSI七层模型 TCP/IP协议
===================================
应用层 应用层
表示层
会话层
===================================
传输层 传输层
===================================
网络层 网络层
===================================
数据链路层 网络接口与物理层
物理层
===================================
【3】UDP TCP 协议相同点
都存在于传输层
TCP : 面向连接,可靠
UDP : 无连接,不可靠
【4】Socket
是一个编程接口
是一种特殊的文件描述符 (everything in Unix is a file)
【5】socket类型
流式套接字(SOCK_STREAM) TCP
提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。
数据报套接字(SOCK_DGRAM) UDP
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。
原始套接字(SOCK_RAW)
可以对较低层次协议如IP、ICMP直接访问。
【6】IP
网络号 + 主机号
【7】TCP通信流程
TCP服务器端
1. socket()创建套接字,这个套接字用于连接。
2. bind()绑定函数,IP和端口与socket的返回值进行绑定;
3. listen()监听套接字,socket()的返回值是文件描述符,默认属性是主动的套接字。
由主动套接字变为被动套接字。
4. accept(),阻塞等待客户端连接;如果有客户端连接,新创建一个套接字,
这个套接字用户通信,通信套接字,进行数据收发;
5. write(),read()
6. close(); 关闭文件描述符;要关闭两个套接字。
TCP客户端:
1. socket()创建套接字,这个套接字用于连接。
2. connect(),发送连接请求;
3. write(), read();
4. close();
【8】
socket()
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能: 创建套接字,用于连接;
参数:
domain: 协议族
AF_UNIX, AF_LOCAL 本地通信的协议
AF_INET IPv4 协议
AF_INET6 IPv6 协议
type:
套接字类型
SOCK_STREAM 流式套接字 TCP
SOCK_DGRAM 数据包套接字 UDP
SOCK_RAW 原始套接字
protocol: 指定协议
TCP UDP
一般填0
255
返回值:
成功返回:新的套接字 sockfd
失败: -1
bind()
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能: 绑定 IP 端口
参数:
sockfd: socket返回的文件描述符
通用结构体:
const struct sockaddr *addr
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
我们要填充的结构体:sockaddr_in inetnet结构体
struct sockaddr_in
{
sin_family ; //协议族 AF_INET
sin_port; //端口号
struct in_addr sin_addr //IP地址
};
struct in_addr
{
in_addr_t s_addr;
};
结构体赋值:
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(8888);
serveraddr.sin_addr.s_addr = inet_addr("192.168.0.40");
listen()
listen - listen for connections on a socket
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能: 用于监听,由主动套接字变为被动套接字;
参数:
sockfd: 套接字
backlog: 设置客户端同时连接服务器的个数
5 8
返回值: 成功 0
失败 -1
accept()
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能: 阻塞等待客户端连接,如果有客户端连接,会创建一个新的文件描述符。用于通信的
参数:
sockfd 套接字
addr
如果服务器端不想关心具体是哪个客户端连接上来,直接填 NULL;
addrlen
NULL
返回值:
成功,返回一个新的套接字,用于通信
失败 -1
recv()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:接收数据 类似于read()
参数:
sockfd: acceptfd 通信套接字
buf: 接收数据的首地址
len: 长度
flags: 0 和read()功能是一样的
MSG_DONTWAIT 设置非阻塞
connect()
connect - initiate a connection on a socket
SYNOPSIS
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:连接服务器
参数:
sockfd: sockfd
addr:
服务器的结构体(服务器的:IP和端口号)
addrlen:
大小
返回值:
成功: 0
失败: -1
send()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据