一、tcp网络编程流程。
1、client端。
初始化socket
解析服务器地址。
connect
send2、server端。
初始化soket用于监听。
解析地址。bind地址,绑定本机的地址。
listen监听socket
accept接收。
select轮训判断是否有数据更新。
二、函数学习。
1、主机字节序和网络字节序。
htons:主机字节序到网络字节序,在解析地址时候用到。
ntohs:网络字节序到主机字节序。输出172.17.3.89
s表示的是uint16_t < 16的。如果是uint32_t则是ntohl和htonl
2、地址族。
分为三种 af_inet(ipv4协议)和 af_inet6(ipv6 协议)和 af_local(unix 域协议)。
3、socket地址结构。
struct in_addr
in_addr_t s_addr; /32位ip地址,网络字节序。
struct sockaddr_in
sin_family
sin_port
sin_addr
sin_zero[8]
struct hostent //用于存储一个指定的主机的信息包括主机名字,ip地址等。
char far* h_name; /pc的名字 (far是编译方式)
char far* h_aliases //
short h_addrype //地址类型。
short h_length //长度。
short h_addr_list //网络地址数组。
4 初始化socket
socket(int af, int type, int protocol)//af为地址族,protocol协议。
type分为两种类型:sock_stream(流模式)和sock_dgram(报文模式),如果是tcp则用流模式,如果是udp则用报文模式。
成功则返回一个描述符,否则返回invalid_socket
5、gethostbyname(char far* name)
根据主机数组的某一个主机名字获得相应的主机信息。返回值类型为hostent
成功则返回一个hostent类型指针,否则返回一个空指针以及错误码。
6、connect(socket s, const struct sockeaddr far* name, int namelen)
s 为未连接的socket的描述符。
name为建立连接后的socket的名字。
如果成功,该函数分会为0.否则返回为负数。
7、accept(socket s, struct sockaddr far* addr, int far* addrlen)
响应连接函数,该函数响应连接请求,建立连接,并返回一个新的socket描述符来描述该连接,用来与特定的client交换信息。返回的信息被存放在addr中。(可以这么理解,返回的新的连接描述符为服务器socket的副本,用以描述一固定客户端的连接)。
s为放入了监听列表中的socket
addr将在函数调用后被填入连接对方的地址信息,如ip和端口。
该函数在成功时返回socket描述符,失败返回-1.
另外,accept为阻塞函数,该函数在没有连接请求时一直阻塞。不会继续执行下面的**。
8、listen(socket s, int backlog)
该函数将需要链接的socket放入监听队列中。其中backlog队列中最大数目。
成功返回0,否则返回错误信息-1.其中backlog是有作用的,只是每次接入连接后,数目就会减一。因为当连接的数目大于backlog并不一定就是请求连接失败。
9、bind(socket s,const struct sockaddr rar* name, int namelen)
该函数将本地地址(端口和ip地址,由于一个主机可能有多个ip地址,所以为inaddr_any
表示为该主机上任何一个ip地址)与socket连接在一起。通常用于服务器端。
成功返回0,否则返回-1或者socket_error,常见的绑定错误是该端口已经被其他程序绑定。
10、select(int nfds,fd_set far* readfds, fd_set far* writefds, fd_set far* exceptfds, const struct timeval far* timeout)
轮询选择函数,该函数对于所有建立链接的函数进行检测相应的链接中是否发现数据更新。如可读、可写。
如果说是每个线程中单独处理一个socket,那么超市可以设定为null,让select一直等待和查询,而如果是一个线程中,处理的是一个socket数组中,那么需要一个超时设置,否则在等待时,如果第一个s一直都是没有发生变化,即不可读不可写,则程序一直阻塞无法进行下去。
int nfds为查询范围,通常为最大的(max)s+1
程序执行成功返回数据更新的s的数目,如果为0表示超时了,负数表示错误。
11、sendto和recvfrom
发送和接收函数,在udp中使用,sendto(socket s, const char far* buf, int len. int flags, const struct sockaddr far* to, int tolen)
s为socket描述符,有可能是已经连接上的。
buf为需要传输数据的buf
len为传输数据的长度。
flags 选择方式(msg_domtroute, msg_oob,oob 仅适用于stream类型数据)
addr 为目标socket的地址。
tolen为目标地址的长度。
该函数成功则返回发送的总数目,否则返回socket_error
recvfrom(socket s, char far* buf, int len, int flags, struct sockaddr far* from, int far* fromsize)
s为已经绑定的地址。
flags有两种,msg_peek 和msg_oob
成功返回接收的数目,如果接收到0表示连接关闭,如果接收到的为负数表示发生错误。
12、send与recv
send(socket s, const char far* buf, int len, int flags)
s 为已经连接上的socket
buf为传输数据的buf
flags为调用的方式(同sendto)
传送成功则返回发送的数目,否则返回错误。
recv(socket s, const char far* buf, int len, int flags)
同send返回为接收到的数目,如果是0表示连接断开,负数表示错误。
13、fd_set
struct fd_set
u_int fd_count;
socket fd_array[fd_setsize]
fd_array为socket的数组。
该数据类型主要应用与不同的sokcet函数,以检测连接变化。如select。
操作有:fd_zero 将集合初始化为0
fd_set(s,*set),将s加入一个fd_set的集合。(是不是将有连接的放入fd_set中,那么检测的时候为什么是检测是否还在该集合中,时表示没有数据更新该集合就已经被移除了吗?还是说加入的时候就是加入的有数据更新的s?
)fd_isset(s,*set)判断s是否还在fd_set中,如果在该集合中表示s可以读或者可以写,即有数据更新。从而进行操作。
fd_clr(s,*set)将s从集合set中移除(为什么我使用失败?)
sockaddr与sockaddr_in
sockaddr
u_short sa_family;
char sa_data[14];
根据所选择的的协议不同,sockaddr的结构会有所不用,除了sa_family,sockaddr的内容都是网络字节序的结构。
sockaddr_in 是sockaddr结构形式的特定互联网地址族,可以转化为sockaddr
short sin_family; /af_inet
u_short sin_port; /ip端口。
struct in_addr sin_addr; /ip地址网络字节序。
char sin_zero[8使结构体的长度和sockaddr保持一致。
适用于tcp/ip.
in_addr
unionstruct
unsigned char s_b1;
s_b2;s_b3;
s_b4;s_un_b;
struct
unsigned short s_w1;
s_w2;s_un;
unsigned long s_addr;
s_un;in_addr
2、sendto和recvfrom
标注为flags一般为0,改变flags将会改变sendto发送的形式。
msg_dontroute勿将数据路由出本地网络。
msg_oob 如果协议支持,发送带外数据(带外数据:在数据传送过程中,希望不通过常规阐述方式传送给用户以便及时处理的某一类型系如unix系统的中断键(delete或者control-c)、终端流控制符(control-s和control-q))
3、端口:抽象的软件结构,用于唯一标示不同主机的进程。tcp/udp中用16为端口号标示用户进程。
4、网络字节顺序,不同计算机算放多字节值顺序不同,有的是其实地址存放地位字节(低阶先存),有的是起始地址存放高位字节(高阶先存),为保证数据的正确性,在网络协议中,指定网络字节顺序。
5、accept()函数机制:用于面向连接服务器,参数addr和addrlen存放客户方的地址信息。调用前,参数addr指向一个初始值为空的地址结构,而addrlen的初始值为0,调用accept()之后,服务器等待从编号为s的套接字上接受客户连接请求,(s为本地套接字描述符,调用过listen(),监听的套接字)。
而连接请求是有客户放的connect调用发出的。当有连接请求到达是,accept()调用请求连接队列上的第一个客户方套接字的地址及长度放入addr和addrlen,并创建一个与s有相同特性的新套接字号,用于处理服务器并发请求。
网络编程学习笔记一
网络编程学习笔记一 socket编程 目录 1.网络中进程之间如何通信。2.什么是socket 1.socket一词的起源。3.socket的基本操作。1.31socket函数。2.32bind函数。1.网络字节序与主机字节序。3.33listenconnect函数。4.34accept函数。5.3...
dom编程学习笔记
一 dom编程。a 基本概念。dom document object model 文档对象模型。其实就是将一些标记型的文档以及文档中的内容当成对象。为什么要将这些文档以及其中的标签封装成对象呢?因为可以在对象中定义其属性和行为,可以方便操作这些对象。b dom在封装标记型文档时,有三层模型 dom1...
编程学习笔记 初级
1 alt enter快捷键 cmd窗口最大化。2 显示命令行帮助信息。3 color 设置默认的cmd窗口前景和背景颜色。4 dir 显示目录中的文件和子目录列表 例 dir d 5 cd 显示当前目录名或改变当前目录 例 cd d 表示上一级目录 表示当前目录 tab键 自动匹配 表示根目录。6...