|
[size=13.3333px]一 三种类型的套接字:% g* L( S5 e V# G8 r: b) K
1.流式套接字(SOCKET_STREAM)& B O. \5 z; y( G: B( M
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。+ C) n: P7 f% J3 E8 z1 ~
2.数据报式套接字(SOCKET_DGRAM)
$ m5 R' N$ a- R" i 提供无连接的数据传输服务,不保证可靠性。
* \3 r0 W3 f1 g5 v5 A7 {3.原始式套接字(SOCKET_RAW)
" p8 Z. Y2 [6 o 该接口允许对较低层次协议,如IP,ICMP直接访问。
0 _( p" r& `' ]. ~% |
( H# \, d2 `( i, B2 ^* s& o二 基本套接字系统调有有如下一些:
" s1 N3 x4 V4 n" c. ` 创建套接字: socket()* ]' p1 f5 d0 L; j/ e& C( X/ C
绑定本机端口: bind()' Y! c! S6 J; F; O' H
建立连接: connect(),accept()
5 Q: q, O H# R2 b& N 侦听端口: listen()
3 D8 D) t4 B4 I+ ~" ^ 数据传输: send(), recv()
- Q/ }) F6 `. X, W t: E 输入/输出多路复用: select()7 s! k- j- f' F" d; ?( M
关闭套接只: closesocket()8 w+ W, }* B3 R5 f& u3 e" `
! [6 b: _ Z' n( R' x
三 数据类型( R# o) ?9 z* X- i& F6 ~
struct sockaddr
5 b: g4 W D, [2 [7 E3 ] {
( o9 v; l' r& k& h0 F- M" h( N unsigned short sa_family; //地址族, 一般为AF_INET" z( q/ B! a( ]0 D& _! v( D& z9 }
char sa_data[14]; //14字节的协议地址' z: H# o$ V+ \4 d' A4 n, E
}
{0 x4 S6 g9 y5 ~$ d) P- i0 r S+ g X" ^. q
struct sockaddr_in
" R* R' J/ i1 P2 k4 T" a5 a {) H* ?/ V' W' \1 u3 {, t- y$ o9 c
short int sin_family; //地址族) C- E; X" p& v- U, [
unsigned short int sin_port; //端口号5 n. V f' z9 }% h) o9 W/ u
struct in_addr in_addr; //ip地址9 u6 `, X( f c& X
unsigned char sin_zero[8]; //填充
- a% Z5 W; v8 y: d" X \ }
4 V' c& v' W5 `' g4 L
h3 j( L0 l5 p四 常用函数1 ? w4 Q9 M Z6 X8 G
1 socket()
7 r, G) a1 n. V- v! ?! @! I 头文件:
4 R! t# S3 v0 L _ #include <sys/types.h>
3 B2 ]; E9 [" e" Q, C. k7 Z. \7 p #include <sys/socket.h>
2 A7 N* ~# a- |; w$ H 函数原型:
% _1 q5 a/ p" F( z n' \ int socket(int domain, int type, int protocol); d% q# W L7 o
domain: 协议类型,一般为AF_INET
- c5 \, o" e. c: e( E' O3 g type: socket类型
% `/ f" K( l: J" a6 `; K protocol:用来指定socket所使用的传输协议编号,通常设为0即可/ t" n- A! F2 z c
7 ]# q" K) \( `9 P6 J4 i Y
2 bind()* A ?2 S; n- r4 b! | t L3 x
头文件:
. M/ F* ]: ^8 F, w$ Q$ f. R. t) i #include <sys/types.h>$ F( l: \- w8 E) e T$ g
#include <sys/socket.h>
9 c3 }5 I1 l0 Z* G 函数原型:& _8 ~) e$ d1 ?, z) w
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
5 F/ |2 ]; _ d0 G* x4 Y: C F$ }6 x sockfd: socket描述符; j4 U, c6 ]- _8 b) P% A
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针4 @/ f' \2 Q6 O- p
addrlen:常被设为sizeof(struct sockaddr)
& a% m" h, H Q, W* p4 V1 |, T5 C; ]% x! o) ]4 q- t
3 connect()3 i) }1 g- s/ U) y c/ ?) w
头文件:: y: ^( J8 M$ m K7 Y
#include <sys/types.h>
# R9 M7 n* r/ S #include <sys/socket.h>
2 ]! f0 d9 k0 v( v4 Q! q 函数原型:) B: X6 K/ H7 E; h' ?
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
' p1 @" M: P8 a5 j9 [% C sockfd: 目的服务器的socket描述符7 M7 [7 C) g9 E+ `2 _) T
serv_addr:包含目的机器ip地址和端口号的指针
+ g$ _' Y2 U. j! \* D& g- R addrlen:sizeof(struct sockaddr)9 ?. F$ M, p7 V, K o
9 W( c* @0 S1 m! Y1 u& i4 b
4 listen()
3 [: X) E: \/ S( ]( I/ m 头文件:9 t9 Q5 m$ a1 S+ b
#include <sys/socket.h>6 L7 _4 O, g# _. \1 f6 Z
函数原型:' |9 c+ ~4 Q% G
int listen(int sockfd, int backlog);
9 Z7 Y& j! Z3 w, e sockfd:socket()系统调用返回的socket描述符
3 ]0 v( N5 [3 h9 H- X+ B! E/ @ backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
0 l, v) K: {5 ?- g; o/ Z0 S6 A2 x" v' y: \; y) |8 B
5 accept()
1 ?/ y1 w" p0 M: e0 p 头文件: 7 G9 q* x) O' f7 t: _. o
#include <sys/types.h>
5 n. v1 d w ?( K& d #inlcude <sys/socket.h>
2 |& R6 G3 D0 J$ {3 z 函数原型:" T. L! _4 `, w$ W- r5 i: D) Y7 t. n
int accept(int sockfd, void *addr, int addrlen)) ] C* E' k! X
sockfd:是被监听的socket描述符
5 ?$ ?! S ~/ I6 J# d' x% H addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
( p2 ?$ S6 z* N& x0 w addrlen:sizeof(struct sockaddr_in)8 R7 D0 t k6 P: f: m5 M
3 v% B3 O2 \; ^$ X( ~ 6 send()
3 {0 S: {/ a$ o# ?4 c) K8 r, j/ C 头文件:
7 |- z$ S! O. ?+ e3 B6 o0 K" s6 o #include <sys/socket.h># B* j% b$ u5 }, a" T7 i$ P
函数原型:
/ x5 Z, {* V5 y5 s int send(int sockfd, const void *msg, int len, int flags);
4 d9 o& A6 @" c, f7 B. \7 O sockfd:用来传输数据的socket描述符
/ o* ]4 ~8 s6 w1 [ msg:要发送数据的指针
, C9 D S: ]. I flags: 06 r* k# P/ G0 P Q
8 b4 e$ L' E1 W2 [- M* l 7 recv()' i7 p5 S$ v1 N5 d! y
头文件:
* }( x7 V; r# i5 g #include <sys/types.h>
4 i- K+ E0 a8 ?7 ?/ q3 E #include <sys/socket.h>6 P5 _% B3 W0 z- i# @ c) n2 h3 l
函数原型:4 \: e) d: R( q/ c/ P6 ?
int recv(int sockfd, void *buf, int len, unsigned int flags)8 g6 s# g/ E% D/ N& }+ s
sockfd:接收数据的socket描述符 x, c0 `+ \9 y% ~9 k5 k
buf:存放数据的缓冲区
1 V1 e3 d1 ?1 t. P* F7 W a" u( Z len:缓冲的长度
' O0 [* s7 J; r$ \* z+ ^ flags:01 @6 B8 p% ~- A2 \6 F- m
# d+ B0 O) Q* Q
8 sendto()
. Y' ]6 m, y3 n( m 头文件:
: [+ @: X* o! e* |# n& ~ I #include <sys/types.h>. P3 ]: l7 w/ j! L$ u( D9 A u
#include <sys/socket.h>
2 R$ i; u( [5 E/ `# }5 u 函数原型:! F' I/ _2 R/ g& [! [: g \
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
- O' ~' ?. |2 Y" [: Z7 n
/ j# u: U7 ~1 j' l& M 4 e( T2 A2 w& ]1 A. w8 Q4 D* v6 O
9 recvfrom()
5 v) j' b+ v3 F4 ~ 头文件:, ~+ u( Y3 f( r8 E! r- L$ [3 M
#include <sys/types.h>* ^1 q/ e6 ~% X! ~+ V
#include <sys/socket.h>
$ ]" V8 m3 r5 }5 h8 u; y 函数原型:
, L. n5 }# N- f, J! l+ l int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen) D4 T4 f6 F+ l
& F/ Z8 |5 i5 h5 r
/ N; O; u8 |) T& ]$ K& Y 10 read() write()
% ^) S2 _1 u# z9 i int read(int fd, char *buf, int len)2 p6 _# G; X+ {+ A0 Y/ e5 L
int write(int fd, char *buf, int len)# v% A4 j7 w2 `0 c
7 c: V2 K* V- ~9 l
11 shutdown()- D. O& f5 I- }# F& N
close(sockfd)
( I( R: Y [; u2 e1 |# c7 M int shutdown(int sockfd, int how)
; s2 }0 M1 ]5 }! i----------------------------------- [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等) 8 _* Z1 }% W8 t' s1 W) k+ n2 |
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等& h, J$ P% l4 H9 e3 q
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()/ i1 T: T1 p- Y% o: _$ l6 p# v
<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
, T* ~$ k8 E; {<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
% ?, R4 k7 g: W( s. I<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
4 p0 a, w* v0 J& C<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
9 K% W$ }5 d. k3 a* L0 ^8 |. u) g" Y6 u T$ q4 }
[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等% K5 c p9 P3 A5 q
#include <sys/types.h>
' N4 m3 R" K4 F+ o$ a; T# O7 G6 s
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
6 l- L7 c5 j% | }2 R# n#include <poll.h> //poll,pollfd
9 x4 |2 t' M) T# ] p" ?#include <arpa/inet.h> //inet_addr,inet_aton
# O" L9 f7 }' e4 s% E#include <unistd.h> //read,write8 x! L+ ]! D" D* A |, a
#include <netdb.h> //gethostbyname0 E5 i7 e. C* r- P/ X9 a
# m+ p# E! t8 s1 ?& R( ^0 [9 T#include <error.h> //perror
( w# D( i- u# \. C" T#include <stdio.h># d" A, n% s) v; B; g+ H5 R
#include <errno.h> //errno
4 y: X7 B0 l( s4 |9 `0 N% l, o
& W: n5 p& T0 g* u: O6 B a9 O#include <string.h> // memset# U5 C( ]: A* a% I9 \
#include <string>
2 O& n% M$ L5 D1 T2 V- X#include <iostream>0 O: z: n: ?! C( q1 q
: M3 a1 f1 ^9 `0 v M |