|
[size=13.3333px]一 三种类型的套接字:" o+ y4 I) h% `% T3 {8 v" Q. n6 f
1.流式套接字(SOCKET_STREAM)
4 y5 I# [5 v% ~) X0 {$ q8 T$ D 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。
3 c7 v% J, O2 D/ {2.数据报式套接字(SOCKET_DGRAM)
6 U. X$ S6 L# D4 L& v& ~/ x# y 提供无连接的数据传输服务,不保证可靠性。 Z+ T3 I2 q/ O* L+ E0 I( ^
3.原始式套接字(SOCKET_RAW)
# J9 c2 A! v1 }- `9 \ 该接口允许对较低层次协议,如IP,ICMP直接访问。
* @" A3 J, X; @( I, k% M; {" {# ^* x6 X* P0 }8 p! a
二 基本套接字系统调有有如下一些:) Z4 `1 S' Z- O, S1 @
创建套接字: socket()
. }$ B/ M0 X+ h5 s- P 绑定本机端口: bind()
, a5 v/ P+ s# m. @- [ 建立连接: connect(),accept()
% x7 L- x' B$ | L 侦听端口: listen()
& O+ k9 Y1 M J 数据传输: send(), recv()# E7 c- M1 U9 B1 c' f3 z
输入/输出多路复用: select()
4 j2 s0 b4 J& k% i; q) H1 Q 关闭套接只: closesocket()
. I9 x" t \ p/ ~3 O$ @ 7 z8 |: q' f& C& E: u4 B
三 数据类型# e+ } g) M& y' E5 ^
struct sockaddr
& j$ K+ {5 l5 Y2 E- f, E* e {" n) z# }' o4 q* W( x- n
unsigned short sa_family; //地址族, 一般为AF_INET
! ?7 P9 j% V; |0 a1 m5 B8 |3 O3 w char sa_data[14]; //14字节的协议地址
- J" s, M( o' F* N7 V4 p$ z }
% g* Y3 K' H* x, J2 `1 p
$ j$ X% o) ~+ s$ f1 e* t- K* ? struct sockaddr_in
% |1 X0 F1 R& H9 n6 u {: q$ G/ K- j) ]( B$ g: W+ Z
short int sin_family; //地址族9 E E( X# v5 x7 L" B
unsigned short int sin_port; //端口号
) n* ]5 b. E p- G$ F struct in_addr in_addr; //ip地址
% P8 a6 F* _# | unsigned char sin_zero[8]; //填充' p/ |0 y. ]$ ?8 O) ]7 }6 q$ q
}
; S! u( b# e7 B( z- `, O9 s5 \, R& ?7 ?+ U* W* }
四 常用函数: B8 n) {+ x# p6 \' j$ N
1 socket()
4 f3 r1 E# I5 w/ | 头文件:
( w1 l6 `4 e1 F$ y+ F: J/ B8 ~5 E #include <sys/types.h>! B$ E6 T/ P( ^ q. a
#include <sys/socket.h>
2 q8 Z9 k8 u: o$ e2 z9 ~! C7 g* x 函数原型:
' A! {0 o8 G+ c* Z# P! s int socket(int domain, int type, int protocol)
( S& K$ h4 k! b2 b+ k domain: 协议类型,一般为AF_INET1 L. N0 x4 W# J- n! W5 p" h9 t3 e
type: socket类型, l% r+ E4 q. G% z2 ?4 W$ _' J
protocol:用来指定socket所使用的传输协议编号,通常设为0即可
; C. R( Y# j/ B5 Z0 o: Q/ ]$ v' C
# @+ z* j* J' ]9 u8 N" O& t" s! V 2 bind()
" ?2 V" V/ M6 g3 [: P 头文件:
+ W" k( n$ m5 O1 U! X1 ^ #include <sys/types.h>
; e- E, A! h7 B) q: w; J #include <sys/socket.h>
- C0 y. K4 `8 E* j" L 函数原型:
1 k. `+ o8 C* K1 Q4 B9 u% P) h) R L int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
9 \* y+ q( B; N sockfd: socket描述符) k4 V' m8 m( D8 c2 R
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针6 Q# _ d; Q% N p9 y& D8 @- I
addrlen:常被设为sizeof(struct sockaddr)3 D4 P2 O) }0 u9 G: v2 _ s# s. _8 t
% n, c Q6 X: p, I& E9 s" u. ]. N$ H: @ 3 connect()% f, G2 U' N$ }8 t
头文件:
8 t0 _3 _- t! ?: S1 V #include <sys/types.h> 1 I# F0 s; Y, M4 w+ I. E& x4 k
#include <sys/socket.h>) x0 @! S: k8 f" a( q
函数原型:! c1 t9 V+ p7 ^1 E. I0 u" G$ m% V6 Y
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
1 j4 _8 p' I) J2 T, H sockfd: 目的服务器的socket描述符) \2 i# s. n1 V3 l; O0 s4 @
serv_addr:包含目的机器ip地址和端口号的指针
0 x, c4 S& {3 x3 h6 w, D addrlen:sizeof(struct sockaddr)) r5 t+ a# U a* F4 c _$ H
* ?; v) \( Z+ q. N& ^' h 4 listen()
3 ^" E/ i* f5 U# i' i 头文件:
" }8 [7 P0 F$ R& `0 t #include <sys/socket.h>
8 b7 l/ ^/ r$ e2 P" l 函数原型:
. f: y r/ H0 u) ?) r) G$ e int listen(int sockfd, int backlog);1 F, i3 G9 X; J( R0 d" h7 z5 ~& K( f
sockfd:socket()系统调用返回的socket描述符
& m t) D" I, [' h backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
1 ^/ s2 u! f9 I2 B6 e8 D6 p3 i9 Y0 g3 C2 T: d0 c
5 accept()
$ N l( T8 h5 u+ x, Q0 `! Z+ j- t% v! ^ 头文件:
" f1 {9 K% j) t9 ~% u8 Q+ Z9 B #include <sys/types.h>
) D7 j4 ~) k* M) e3 J #inlcude <sys/socket.h>
8 s, P8 m y( k- x! ^0 B 函数原型:
. E: T6 n+ q% _# ~5 [ int accept(int sockfd, void *addr, int addrlen)- X4 ^' _- U* G
sockfd:是被监听的socket描述符
$ j Q& U- z( y0 N) Y addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息" A0 K' b+ E- D- j
addrlen:sizeof(struct sockaddr_in) j0 ?8 x8 }6 R0 u2 {
3 o2 a% e+ n* n) g2 x+ T
6 send()9 X: R {' U% H7 Z; o0 K2 b; `
头文件:
6 E5 v! s0 M8 V #include <sys/socket.h>. v9 ^; C) k& q, u- q$ a5 |7 d
函数原型: X0 B- s* ~9 n6 r1 D
int send(int sockfd, const void *msg, int len, int flags);
, L& y: [& M) V8 H. d6 ~6 B sockfd:用来传输数据的socket描述符& g1 W8 ]0 }5 N
msg:要发送数据的指针
/ [3 e" c; a$ | flags: 0
) n W! t. v! j$ s
" F: \+ A/ q9 s" ? 7 recv()
" J9 F1 ~ a/ F. y" D; r ? 头文件:- t4 r8 q) k/ Z9 I
#include <sys/types.h>
+ l, W' a5 U3 t" X. K0 \' E, @ #include <sys/socket.h>+ J; M& w- {8 X+ b: {4 C+ D# U5 F
函数原型:
7 r2 r, {; g$ k7 w8 m9 ? int recv(int sockfd, void *buf, int len, unsigned int flags)& n. T8 q2 H$ W+ S" p. i( ^
sockfd:接收数据的socket描述符$ a- u$ D- g8 Q' q* K( M% p- A
buf:存放数据的缓冲区3 ~; Q* t- D% X
len:缓冲的长度
: m5 Q [& I8 o0 P flags:07 Q2 Q5 u, Q( ^( Z% Y
* `# f Q- G+ b 8 sendto()
9 R$ S' C( W5 B, ]4 o' H% { 头文件:
: e1 t" C$ h; f #include <sys/types.h>; r7 y8 b; j+ V- G& ^
#include <sys/socket.h>8 o' h& y+ c S& y3 K8 K
函数原型:
) w3 V, D( H9 d; M7 d: L; { int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
# y8 K; {1 z s, i) d4 U) n3 {8 _( g 5 [- C- G& b" e0 [2 K5 X, u) N9 [
`1 b+ M: s- G( j) l. l8 P 9 recvfrom()
+ E9 e. _% C! z' m- p, { 头文件:
, J9 t7 ~' `7 A* y( s% H #include <sys/types.h>
" T0 k9 \; q- N5 u #include <sys/socket.h>: ?* i n1 K: B) R+ `; a, a" F' C
函数原型:
9 Z8 `3 g2 i$ s- p! r0 `7 q7 y int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
: a% T7 k9 S4 B+ E( }' ]- h1 T
% O' ]9 ~6 [* t7 h% U# J. w( E
( {' c5 [* e* s1 W 10 read() write()- G( |2 ]3 @9 W
int read(int fd, char *buf, int len)
& G; }. ]" r( B: q int write(int fd, char *buf, int len)2 W- j0 g, \# ]3 K4 j" D- k
/ i: ^! C" Y. K Q& c1 U8 J
11 shutdown()
0 f' x& ?& S: }: d! P# d close(sockfd)
* C/ z3 a* s9 f$ X int shutdown(int sockfd, int how)
m: f+ O( i* O5 o; \5 Y' j----------------------------------- [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$ T% ] p y& Z! v$ e* [
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等7 E- I% E3 J1 d! {$ z
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
4 l- Q% e! a0 J& Q M<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
. `) y0 ~' N( V<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等, |+ Z' I2 {) g, z; l, s
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
^+ e) T& Z' u* X9 X- r% d<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件 J2 I9 X2 F; \0 g
, [/ ~( T% [: H- |" E[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等8 Y# m9 j* j1 \9 b! o( G
#include <sys/types.h>
9 {- x) n+ W) E2 h5 u$ l$ A8 M7 x- `- U4 p
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
. n& |5 t4 K A1 m- _3 R#include <poll.h> //poll,pollfd' k: F# D% L" m c# E) ^% c, _
#include <arpa/inet.h> //inet_addr,inet_aton! J) v' S7 Y/ s
#include <unistd.h> //read,write
7 u1 ]9 A G+ d* }0 W0 R! v#include <netdb.h> //gethostbyname* [: J6 Y$ S( @& E! v0 u) V
( P. _8 O! k! ^$ p8 a2 C. [#include <error.h> //perror
: ~8 N$ W- O9 G$ \) ]#include <stdio.h>
( K) w9 F- J, B- H3 {4 S) u6 }#include <errno.h> //errno
" y, {9 s: V% s7 h. I: ]0 x7 ~. O$ J J/ \" g
#include <string.h> // memset
" L( S2 j7 R' \$ T) j#include <string>4 V. Y0 ]7 W# k, ]0 |
#include <iostream>( m8 V* M; t: N
& L# t/ ~( J. U9 f( {
|