|
[size=13.3333px]一 三种类型的套接字:
0 A* O/ p1 C+ R! X y% R+ r1.流式套接字(SOCKET_STREAM)
( W4 b7 r" @. Q& H: V1 F8 L 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。; V) }3 E9 r: J7 W. `6 s; M
2.数据报式套接字(SOCKET_DGRAM)- E) ], B$ x, {- a
提供无连接的数据传输服务,不保证可靠性。
2 Q+ E+ I2 U. m+ D4 ~3 U3.原始式套接字(SOCKET_RAW)) |4 ]" ~( d d: c8 a/ W2 ?* T
该接口允许对较低层次协议,如IP,ICMP直接访问。
" T" t4 A2 N. e& Z6 V
2 D7 _! ~; p8 J! [1 D' c8 ~. a二 基本套接字系统调有有如下一些:
. q7 S% Z1 ~. k9 F; d 创建套接字: socket()
6 k+ X8 C8 x9 F 绑定本机端口: bind()6 K: Y! O# }: M2 N) f$ y
建立连接: connect(),accept(), {# D( j% Q3 O4 m/ U% u+ p
侦听端口: listen()
6 X1 ~5 q. n r9 i( n 数据传输: send(), recv()
- D9 c2 M' f: _" }9 L) W/ r3 ~; w 输入/输出多路复用: select()) _ P; C3 X: w& \/ R
关闭套接只: closesocket()! q+ E$ l$ Q* o8 {0 ]% ?1 X/ @
: m, p- N! ~$ M( O- N ^三 数据类型
0 I' b8 a' a6 p' \4 ^: ^ struct sockaddr+ f! k; m& U$ t" U
{/ o/ o; N0 N0 p: G
unsigned short sa_family; //地址族, 一般为AF_INET% g) z: O9 u& w5 w+ l! e4 r2 s$ K
char sa_data[14]; //14字节的协议地址
K) `4 h3 [, J- o& a! z }- K" ]* I! N) ]9 E$ Z/ L
6 V \4 Q7 P7 z' X- o- J
struct sockaddr_in
' o) s3 S! c& I$ M$ c {
8 P$ _- k( M. X5 l7 K short int sin_family; //地址族! z5 N1 \ y, p) _# B5 f
unsigned short int sin_port; //端口号+ e. d ~7 b4 Z8 Y% [
struct in_addr in_addr; //ip地址& R* Q' f. s/ O5 L
unsigned char sin_zero[8]; //填充
& O& O% M3 N( ^' d4 B9 I! { }
' N, e/ ~& d- O. K/ z( t, P
$ l. Q1 a: S. R i5 @. C5 Q3 T四 常用函数
% O% {% k) Q# R. @ 1 socket(). C) ]: W7 V. k9 H; _
头文件: " G- L! Q* }3 r7 P _! F
#include <sys/types.h>- |4 D3 Q, T- C9 S8 E1 c% r
#include <sys/socket.h>3 d- [" J t5 h( w- h t
函数原型:
' h9 f ?+ e X$ |. p% l: h# Q( u; [ int socket(int domain, int type, int protocol)# k3 i) T# }3 m% P# C! f# Q: F1 ]5 p
domain: 协议类型,一般为AF_INET
% G" K& n' J1 n+ k type: socket类型2 C: S' f( T# z( Q
protocol:用来指定socket所使用的传输协议编号,通常设为0即可
6 M1 w2 b ]4 |
' p7 h H: C& ]5 g 2 bind()8 `; N0 f% c, T0 X `4 l7 F% P
头文件:
# c; k% s+ ~9 Y #include <sys/types.h>
l8 J& d/ C- n; L #include <sys/socket.h>
4 M1 u* A. h9 L7 |9 ~, O4 D 函数原型:
Z+ {5 {4 I! u2 C2 ? int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
& N' ]' \2 G' x9 i& {/ ] sockfd: socket描述符7 i" y$ o" n# c
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针1 X( Y: g: o+ S
addrlen:常被设为sizeof(struct sockaddr)
' R$ S5 f* X( d/ C6 p4 Y) F
" t$ g3 P1 _$ |# {4 Y& e8 A) J 3 connect()* C8 g# ]7 M6 h( ~
头文件:% a: L# W$ v) ?' y) H2 i5 [
#include <sys/types.h>
+ Q- s) n1 o |4 T" o #include <sys/socket.h>
* `% l% b" ^, { D% t 函数原型:
' X9 I+ [0 u, U2 V1 X; r int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
7 Y" b" ?1 @4 _- l. E$ q+ v" j sockfd: 目的服务器的socket描述符, _6 `7 e3 X, q2 z5 z
serv_addr:包含目的机器ip地址和端口号的指针& e8 q* g3 Q$ r* p
addrlen:sizeof(struct sockaddr)
) M5 A+ v/ ^( X: x! V; P7 }, S! T6 L, Y/ ~# y0 q3 B1 L
4 listen()
* }: ^% g S" H( r; z& Q" i 头文件:. ~$ E; n3 k; @0 a
#include <sys/socket.h>! C1 z6 W- a9 ~" D2 ]! f) N8 m, X
函数原型:* l) w% Y/ G3 n' a
int listen(int sockfd, int backlog);0 N% v: Y& v% s8 S7 _" ~
sockfd:socket()系统调用返回的socket描述符9 {% ~2 M! o+ ?
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
, ]8 ]& O5 R C2 g) T& W9 ]$ Q% J; v' m- O
5 accept()
; x" g0 W g1 r 头文件:
- d7 M- y* E0 G0 f #include <sys/types.h>/ o0 `! O3 t+ r3 {
#inlcude <sys/socket.h>6 @* u0 H, c. A6 F7 X' @
函数原型:1 q' o6 L# J/ y
int accept(int sockfd, void *addr, int addrlen)
% ~# ]& o$ ]' q' h sockfd:是被监听的socket描述符
/ O. P/ B( E4 W! f% j- |9 W4 | z4 h addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
8 G" p! [. K; y+ ?9 w7 q A/ [ addrlen:sizeof(struct sockaddr_in)
6 m) Z5 o. f& K& H
" J6 @! `5 O) M0 l5 t1 [! B 6 send()" [: Q7 R. I7 e
头文件:6 g3 v- ?4 J. ^ ^# y2 a
#include <sys/socket.h>
/ }4 G% O6 M1 J3 v1 q 函数原型:) t: L; Z: ]9 O; f
int send(int sockfd, const void *msg, int len, int flags);
6 O- l: ^& @* Y! f5 d sockfd:用来传输数据的socket描述符- d! A' w( {. j1 a6 ]* a
msg:要发送数据的指针 # w! G( t, H3 O- `) ^
flags: 0% O$ x1 F4 N$ @1 @2 x
M- |* q: `8 K D5 K7 ]
7 recv()
9 P3 m# Y3 P' G' t& B3 i 头文件:4 z3 W" h1 N, J& \
#include <sys/types.h># S/ X& N2 o1 F( w% y9 W
#include <sys/socket.h>2 f( M' `9 s5 {- i' p& p8 S
函数原型:
, w* K* B' r! \0 i- S. S9 | int recv(int sockfd, void *buf, int len, unsigned int flags)
* a9 A# l9 U, Y9 ?4 x3 h sockfd:接收数据的socket描述符
8 j. \- A2 @( m* L, P buf:存放数据的缓冲区& X! h% T1 h6 a" g8 e0 T c
len:缓冲的长度& \3 e! V: n. t4 \$ |
flags:0& U+ D% i4 Z3 ~
' g( T9 Y; L5 w3 X 8 sendto()' a& C/ }4 {+ X, k8 y$ `/ t% [
头文件:
: T8 @' J5 c! ]9 Z #include <sys/types.h>
, I2 ]8 T/ }, ?1 I+ G( D; U #include <sys/socket.h>
2 R+ A7 c4 H' y# H4 g5 a# R 函数原型:
+ l: \2 `# c( j& v int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);! }" m9 `) l+ m' I; H% X4 A/ ^) S6 _3 e9 a
( M; K: R" K( o: x1 z
( T1 ?1 c4 f( S 9 recvfrom()
% B; I1 ]- ^1 j" t8 ? 头文件:, J0 \: A+ Q; @
#include <sys/types.h>
4 j7 j4 d) ^$ ^7 S #include <sys/socket.h>
# p9 u1 ^; F x' ~+ J+ `9 L 函数原型:
; s: d# O7 u/ f( m1 J' ~ int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
' d) \ {: Y {6 O% w
. a+ f7 |0 ^$ ^8 S$ K2 E- Q+ V
7 K% t# V' |, T2 P 10 read() write()) H1 ?- X, X& K+ B$ y5 p3 b: {! W
int read(int fd, char *buf, int len)
4 E; s: D1 F: P7 Z1 S int write(int fd, char *buf, int len)
3 A6 s- i# @* e/ x$ [# P9 l/ l4 V6 T
/ B; j0 ~3 B; ~6 w0 ~# s 11 shutdown(), l' g% M0 g0 [! j, x) a% p
close(sockfd)
! G3 \; g" e# m4 h! e7 E# _; m int shutdown(int sockfd, int how). f* ^2 B7 Y; q* T
----------------------------------- [size=13.3333px]netinet/if_ether.h ether_arp的数据结构 [size=13.3333px]netinet/ether.h 以太祯的网络字节和ascii字节的转换,包括ether_ntoa(),ether_aton这样的函数定义 [size=13.3333px]netinet/ip.h 这个头文件和linux/ip.h似乎很相似,也有iphdr的数据结构,同时还包括了timestamp结构,我的理解是,linux文件夹下的 ip.h是linux黑客编写的ip头文件,而这个则是gnu一开始就定义的头文件,同时还包括了bsd中的ipheader结构定义。同理的还有该目录 下的tcp.h等文件 [size=13.3333px]linux/ip.h iphdr的数据结构,以及一些ip层的数据定义,同理的还有tcp.h,udp.h等等 [size=13.3333px]linux/if.h 主要的socket头文件,似乎修改自unix的if.h,定义了网卡的接口信息的宏,例如IFF_UP.另外有数个重要的interface的数据结构定义,包括ifreq,ifconf,ifmap [size=13.3333px]linux/if_packet.h 原始数据包的数据结构定义,包括sockaddr_pkt,sockaddr_ll,想接收原始数据包的不能错过这个文件。同理的还有if_ppp.h,if_tun.h等等 [size=13.3333px]netinet/in.h 这个文件作的事情就多了。端口宏定义,著名ip(比如loopback),结构sockaddr_in,网络字节转换(ntoh,hton。。。。)。。。反正太多了,没事的话就把这个文件加到头文件包含里吧 [size=13.3333px]netdb.h 文件如其名,包括结构hostent(主机环境),获得主机的信息的几个函数(gethostbyname)。似乎这个就是定义主机的各项环境,例如hostname等等 [size=13.3333px]net/bpf.h berkeley的数据包过滤头文件,想用bpf进行包过滤的要重视一下这个文件 [size=13.3333px]net/ethernet.h 包括几个以太网的数据结构,ether_addr(mac帧结构),ether_header(以太帧的头部) [size=13.3333px]------------------------------- [size=13.3333px]<sys/types.h> //primitive system data types(包含很多类型重定义,如pid_t、int8_t等) # X/ r% B0 Q) |# {* O
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等1 v& g. r: @# H; r; `
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
: }& U- Z" x. ?2 l; A<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
8 \7 o' ?5 d7 T+ z" D6 v<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等6 Z* k4 T! H9 j- ?) _# ?3 S7 z
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等- r( w" u8 z2 b8 q1 ~
<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件5 _0 X% I9 E# t' |. o: g; L+ \1 o
; w% I/ q# f, L* N$ o8 j[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
8 P' q- U; t( q9 O: t5 Y/ Q l#include <sys/types.h> L+ n h3 I; C' S( U) v1 |
# k: D- P( C( m: M1 P/ f9 Q' Z#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons& C m3 `1 k' Y! m& s
#include <poll.h> //poll,pollfd# s5 r$ m0 g# |# h1 ~+ Q
#include <arpa/inet.h> //inet_addr,inet_aton3 E5 n1 D5 ~9 p8 _" u6 u
#include <unistd.h> //read,write
7 ], K0 D4 E3 E1 Q8 q#include <netdb.h> //gethostbyname
* `( F1 t2 E, t. O. r$ c& _6 `$ ~% V3 M8 i( |8 h; F
#include <error.h> //perror# `% {3 G3 r8 U) S' P8 q7 V' P8 ?% m
#include <stdio.h>2 O& n. D, f! c& l* k5 r) F( k- c
#include <errno.h> //errno
% x8 J9 g5 s. N- A
; H1 J& c# t, Z; Q9 |#include <string.h> // memset* d- O6 _- R* l4 |0 l
#include <string>
) V" k8 r4 l& _9 I#include <iostream>2 J1 Z& G a9 f* b( m2 e
4 l! J* F Z1 w" ^1 g+ p
|