Linux网络编程;
ping:调试网络环境。
telnet:远程登陆协议。
DNS:域名到ip的转换。
tcp与ip的区别:
TCP为应用层提供可靠的面向连接的,基于流的服务。TCP协议使用超时重传、数据确认等方式来确保数据包被正确的发送到目的,因此TCP服务是可靠的。使用TCP协议通信的双方必须先建立TCP连接,并且在内核中为该连接维持一些必须的数据结构。当通信结束时,双方必须关闭连接以释放这些内核数据。
UDP:则与相反,它为应用层TCP协议完全提供不可靠、无连接和基于数据报的服务。如果数据在中途丢失,或者目的端通过数据校验发现数据错误而将其丢弃,则UDP协议只是简单的通知应用层发送失败。因此使用UDP协议的应用程序通常要自己处理数据确认、超时重传等逻辑性。
DHCP:动态主机分配协议。
IP的主要目的是为数据输入/输出网络提供基本算法,为高层协议提供无连接的传送服务它只是封装和传递数据,但不向发送者或接收者报告包的状态,不处理所遇到的故障。
“三次握手” :是指建立一个TCP连接时,需要客户端和服务器总共发送3个包.
“四次挥手” :TCP连接的删除需要发送四个包。
Socket:文件描述符,包括三种套接字,流式套接字,数据报套接字,原始套接字。
地址结构:
struct sockaddr
{
u_short sa_family;
char sa_data[14];
};
Sa_family:
地址族,采用“AF_xxx”的形式,如:AF_INET
Sa_data:
14字节的特定协议地址
struct sockaddr_in
{
short int sin_family; / Internet地址族 /
unsigned short int sin_port; / 端口号 /
struct in_addr sin_addr; / IP地址 /
unsigned char sin_zero[8]; / 填0 /
}; 编程中一般并不直接针对sockaddr数据结构操作,而是使用与sockaddr等价的sockaddr_in数据结构
字节序转换:
大端字节序:(网络字节序):高字节存放在低地址,低字节存放在高地址。
小端字节序:(主机字节序):高字节存放在高地址,低字节存放在低地址。
进行Socket编程的常用函数有:
socket
创建一个socket
bind
用于绑定IP地址和端口号到socket
connect
该函数用于绑定之后的client端与服务器建立连接
listen
设置能处理的最大连接要求,Listen()并未开始接收连线,只是设置socket为listen模式。
accept
用来接受socket连接。
send
发送数据
recv
接收数据
socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调用出错则返回-1
对于IPv4,family参数指定为AF_INET
对于TCP协议,type参数指定SOCK_STREAM,表示面向流的传输协议如果是UDP协议,则type参数指定为SOCK_DGRAM,表示面向数据报的传输协议
服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接,因此服务器需要调用bind绑定一个固定的网络地址和端口号.bind()成功返回0,失败返回-1。 bind()的作用是将参数sockfd和myaddr绑定在一起,使 sockfd这个用于网络通讯的文件描述符监听myaddr所描述的地址和端口号
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);*
首先将整个结构体清零,然后设置地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到不某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为SERV_PORT,我们定义为8000 ;
三方插手完成后,服务器调用accept()接受连接,如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来,cliaddr是一个传出参数,accept()返回时传出客户端的地址和端口号.
基于TCP的服务器:
1. 创建一个socket,用函数socket()
2. 绑定IP地址、端口等信息到socket上,用函数bind()
3.设置允许的最大连接数,用函数listen()
4.接收客户端上来的连接,用函数accept()
5.收发数据,用函数send()和recv(),或者read()和write()
6.关闭网络连接
基于TCP的客户端:
1.创建一个socket,用函数socket()
2.设置要连接的对方的IP地址和端口等属性
3.连接服务器,用函数connect()
4.收发数据,用函数send()和recv(),或者
read()和write()
5.关闭网络连接
基于UDP的服务器:
1.创建一个socket,用函数socket()
2.绑定IP地址、端口等信息到socket上,用函数bind()
3.循环接收数据,用函数recvfrom()
4.关闭网络连接
基于UDP的客户端:
1.创建一个socket,用函数socket()
2.绑定IP地址、端口等信息到socket上,用函数bind()
3.设置对方的IP地址和端口等属性
4.发送数据,用函数sendto()
5.关闭网络连接
**UDP循环服务器**
UDP循环服务器的实现方法:**(思路)**
UDP服务器每次从套接字上读取一个客户端的请求->处理->然后将结果返回给客户机
socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}
TCP循环服务器
TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接。算法如下:
socket(…);
bind(…);
listen(…);
while(1)
{
accept(…);
process(…);
close(…);
}
TCP并发服务器
socket(…);
bind(…);
listen(…);
while(1) {
accept(…);
if(fork(…)==0) {
process(…);
close(…);
exit(…);
}
close(…);
}
int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set *exceptfds, const struct timeval *timeout)
Maxfd: 文件描述符的范围,比待检的最大文件描述符大1
Readfds:被读监控的文件描述符集
Writefds:被写监控的文件描述符集
Exceptfds:被异常监控的文件描述符集
Timeout:定时器
宏FD_SET将文件描述符fd添加到文件描述符集fdset中;
宏FD_CLR从文件描述符集fdset中清除文件描述符fd;
宏FD_ZERO清空文件描述符集fdset;