UNIX C的一篇文章[5]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 gimser 的 blog

ct udphdr {
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
};
关于udp协议的详细情况,请参考 rfc768
7.5 tcp
tcp协议也是建立在ip协议之上的,不过tcp协议是可靠的.按照顺序发送的.tcp的数据结
构比前面的结构都要复杂.
0 4 8 10 16 24 32
-------------------------------------------------------------------
| 源端口 | 目的端口 |
-------------------------------------------------------------------
| 序列号 |
------------------------------------------------------------------
| 确认号 |
------------------------------------------------------------------
| | |u|a|p|s|f| |
|首部长度| 保留 |r|c|s|y|i| 窗口 |
| | |g|k|h|n|n| |
-----------------------------------------------------------------
| 校验和 | 紧急指针 |
-----------------------------------------------------------------
| 选项 | 填充字节 |
-----------------------------------------------------------------
tcp的结构在<netinet/tcp.h>中定义为:
struct tcphdr
{
u_int16_t source;
u_int16_t dest;
u_int32_t seq;
u_int32_t ack_seq;
#if __byte_order == __little_endian
u_int16_t res1:4;
u_int16_t doff:4;
u_int16_t fin:1;
u_int16_t syn:1;
u_int16_t rst:1;
u_int16_t psh:1;
u_int16_t ack:1;
u_int16_t urg:1;
u_int16_t res2:2;
#elif __byte_order == __big_endian
u_int16_t doff:4;
u_int16_t res1:4;
u_int16_t res2:2;
u_int16_t urg:1;
u_int16_t ack:1;
u_int16_t psh:1;
u_int16_t rst:1;
u_int16_t syn:1;
u_int16_t fin:1;
#endif
u_int16_t window;
u_int16_t check;
u_int16_t urg_prt;
};
source发送tcp数据的源端口
dest接受tcp数据的目的端口
seq标识该tcp所包含的数据字节的开始序列号
ack_seq确认序列号,表示接受方下一次接受的数据序列号.
doff数据首部长度.和ip协议一样,以4字节为单位.一般的时候为5
urg如果设置紧急数据指针,则该位为1
ack如果确认号正确,那么为1
psh如果设置为1,那么接收方收到数据后,立即交给上一层程序
rst为1的时候,表示请求重新连接
syn为1的时候,表示请求建立连接
fin为1的时候,表示亲戚关闭连接
window窗口,告诉接收者可以接收的大小
check对tcp数据进行较核
urg_ptr如果urg=1,那么指出紧急数据对于历史数据开始的序列号的偏移值
关于tcp协议的详细情况,请查看 rfc793
7.6 tcp连接的建立
tcp协议是一种可靠的连接,为了保证连接的可靠性,tcp的连接要分为几个步骤.我们把这
个连接过程称为"三次握手".
下面我们从一个实例来分析建立连接的过程.
第一步客户机向服务器发送一个tcp数据包,表示请求建立连接. 为此,客户端将数据包的
syn位设置为1,并且设置序列号seq=1000(我们假设为1000).
第二步服务器收到了数据包,并从syn位为1知道这是一个建立请求的连接.于是服务器也
向客户端发送一个tcp数据包.因为是响应客户机的请求,于是服务器设置ack为1,sak_se
q=1001(1000+1)同时设置自己的序列号.seq=2000(我们假设为2000).
第三步客户机收到了服务器的tcp,并从ack为1和ack_seq=1001知道是从服务器来的确认
信息.于是客户机也向服务器发送确认信息.客户机设置ack=1,和ack_seq=2001,seq=100
1,发送给服务器.至此客户端完成连接.
最后一步服务器受到确认信息,也完成连接.
通过上面几个步骤,一个tcp连接就建立了.当然在建立过程中可能出现错误,不过tcp协议
可以保证自己去处理错误的.
说一说其中的一种错误.
听说过dos吗?(可不是操作系统啊).今年春节的时候,美国的五大网站一起受到攻击.攻
击者用的就是dos(拒绝式服务)方式.概括的说一下原理.
客户机先进行第一个步骤.服务器收到后,进行第二个步骤.按照正常的tcp连接,客户机
应该进行第三个步骤.
不过攻击者实际上并不进行第三个步骤.因为客户端在进行第一个步骤的时候,修改了自
己的ip地址,就是说将一个实际上不存在的ip填充在自己ip数据包的发送者的ip一栏.这
样因为服务器发的ip地址没有人接收,所以服务端会收不到第三个步骤的确认信号,这样
服务务端会在那边一直等待,直到超时.
这样当有大量的客户发出请求后,服务端会有大量等待,直到所有的资源被用光,而不能再
接收客户机的请求.
这样当正常的用户向服务器发出请求时,由于没有了资源而不能成功.于是就出现了春节
时所出现的情况.
----------------------------------------------------------------------------

网络编程(8)

8. 套接字选项
有时候我们要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要控制套接字的
选项了.
8.1 getsockopt和setsockopt
int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optl
en)
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t
*optlen)
level指定控制套接字的层次.可以取三种值: 1)sol_socket:通用套接字选项. 2)ippro
to_ip:ip选项. 3)ipproto_tcp:tcp选项.
optname指定控制的方式(选项的名称),我们下面详细解释
optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换
选项名称 说明 数据类型
========================================================================
sol_socket
------------------------------------------------------------------------
so_broadcast 允许发送广播数据 int
so_debug 允许调试 int
so_dontroute 不查找路由 int
so_error 获得套接字错误 int
so_keepalive 保持连接 int
so_linger 延迟关闭连接 struct linge
r
so_oobinline 带外数据放入正常数据流 int
so_rcvbuf 接收缓冲区大小 int
so_sndbuf 发送缓冲区大小 int
so_rcvlowat 接收缓冲区下限 int
so_sndlowat 发送缓冲区下限 int
so_rcvtimeo 接收超时 struct timev
al
so_sndtimeo 发送超时 struct timev
al
so_reuseraddr 允许重用本地地址和端口 int
so_type 获得套接字类型 int
so_bsdcompat 与bsd系统兼容 int
==========================================================================
ipproto_ip
--------------------------------------------------------------------------
ip_hdrincl 在数据包中包含ip首部 int
ip_optinos ip首部选项 int
ip_tos 服务类型
ip_ttl 生存时间 int
==========================================================================
ippro_tcp
--------------------------------------------------------------------------
tcp_maxseg tcp最大数据段的大小 int
tcp_nodelay 不使用nagle算法 int
=========================================================================
关于这些选项的详细情况请查看 linux programmer's manual
8.2 ioct

本文关键:UNIX C的一篇文章
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top