[size=13.3333px]一 三种类型的套接字:
6 x1 _6 c7 F9 X1 b- O p9 u; C1.流式套接字(SOCKET_STREAM)$ X& b5 g! ~. ~4 E
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。. X2 F# ^* |9 q, w
2.数据报式套接字(SOCKET_DGRAM)7 Y% G. U% [* J+ Y' V
提供无连接的数据传输服务,不保证可靠性。6 `# D; q& k9 h+ U' [
3.原始式套接字(SOCKET_RAW)1 d$ n( w1 A" S# @
该接口允许对较低层次协议,如IP,ICMP直接访问。
& T$ p8 F, s: M( v1 J, y" u" v$ a7 R: S V
二 基本套接字系统调有有如下一些:: L* \0 | {! P% }- E0 G. M y/ D
创建套接字: socket()1 u2 `5 e1 E4 ~
绑定本机端口: bind()$ o) G! R4 u. S0 J$ J
建立连接: connect(),accept(), Q; ]" W; M2 C; P8 J
侦听端口: listen()
8 Q8 G+ n( J4 L1 d l* m2 Z 数据传输: send(), recv(): B* p* A) Z+ \4 e7 c; v
输入/输出多路复用: select()
" q+ N* ^- {9 o- o p 关闭套接只: closesocket()$ t7 k" ~# J- k! v- }
z1 m; y2 \* p' s0 A, |) _三 数据类型$ P* u# G; ?+ D3 C% u6 A
struct sockaddr. l$ d3 F' M6 T& ^/ W0 e
{
1 t7 z9 j: ]# c unsigned short sa_family; //地址族, 一般为AF_INET: b) [5 @! _& ?# D* f
char sa_data[14]; //14字节的协议地址( ]- H: X/ k# ^6 L
}3 n0 x5 @4 V* I/ r, O7 S, v
; y* Y! C" _% h) o; b
struct sockaddr_in
+ i0 g9 Q( a# } {+ e3 K$ p8 p% z; P
short int sin_family; //地址族* Q, R8 i- d/ } g% N
unsigned short int sin_port; //端口号
& C, P# ?& C. ~! j: G struct in_addr in_addr; //ip地址& P- Y3 b% U) c5 o* s
unsigned char sin_zero[8]; //填充
% w5 O& l4 p8 _ }* ]. Y, { N- }; J- X# k
5 f4 M2 x; _* ~) a, l四 常用函数7 ?) V+ X1 L7 g3 P$ [# }
1 socket()
# g( \6 J z; ?% ~/ ? 头文件: 4 `9 S- Q' M# }" N
#include <sys/types.h>& q3 t& G' O! L( N1 C
#include <sys/socket.h>
2 D- O' Y/ u( I6 n, p: V 函数原型:; T0 Z+ F* b! |, y+ e i
int socket(int domain, int type, int protocol)
1 z& }% t2 Q2 f: o domain: 协议类型,一般为AF_INET$ u5 n1 m9 r0 j% t$ k
type: socket类型
0 c `+ ?; T$ ^ protocol:用来指定socket所使用的传输协议编号,通常设为0即可, C2 e3 N+ @7 U& ~+ n' D
D2 P- [0 i( |2 U
2 bind(); m+ d8 a& H h/ E7 {- u6 c' Z6 Y% j
头文件:
& `$ N1 a1 B K) J: h: }/ Q! S$ U3 d #include <sys/types.h>
( G* Y. d5 A) _6 c1 M4 H #include <sys/socket.h>
- v+ w3 a+ f7 `+ C4 f1 s 函数原型:2 K& D7 d. ]4 h8 f; f" K; ^
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)( s! S4 f3 F! @' h! _) T% G( ~
sockfd: socket描述符' Q" W' f/ |* _% v+ A
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针! A' G; G9 Q- N2 a) I, A
addrlen:常被设为sizeof(struct sockaddr)
: S, A9 s# ?4 D1 [0 w: L( o& ^- x" F" h8 `
3 connect() A' x3 A) A3 Z+ R5 ~! M: l7 N( u
头文件:6 `" E5 N+ v- A9 m
#include <sys/types.h> $ \+ ^$ s" M+ X
#include <sys/socket.h>
/ K$ c) K6 e4 J4 {: O 函数原型:
0 B' F! {6 F% _1 `1 R K3 W int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)( Y$ `: n) n; a) V* \3 ^
sockfd: 目的服务器的socket描述符& a6 a% M6 m9 {( w
serv_addr:包含目的机器ip地址和端口号的指针/ O4 ?* @# K3 O0 G6 `' F; k
addrlen:sizeof(struct sockaddr)
% n5 a& P, b0 E, V. i0 b6 J
! |# e$ V _. O% a. J! y6 ` I 4 listen()
! ^/ a3 k9 @+ I$ k/ b 头文件:
) u% Y7 u3 @8 a #include <sys/socket.h>
/ l" e- G) B& V8 X; T, Q7 y 函数原型:
1 T$ M8 L1 N4 h9 C: v0 p int listen(int sockfd, int backlog);
0 P, k" I, k1 O; j" w9 S sockfd:socket()系统调用返回的socket描述符
/ _" \* e5 X4 N- j1 }- R backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
. v) H: T' e2 Y) ~0 K+ k: R
# m, _; G* S7 i9 [! T 5 accept()
2 M( `2 n: s/ z# S9 O3 r! Z5 y 头文件: / j, ]: g' p9 _5 h
#include <sys/types.h>
) g: O' N4 S2 X( Q; k- H #inlcude <sys/socket.h>, t( a, O H8 ~5 l; l: c4 F
函数原型:
8 t' S7 X5 e! R int accept(int sockfd, void *addr, int addrlen)% K$ [6 P8 A8 n! }5 X
sockfd:是被监听的socket描述符
. G% L3 I# r+ j: d+ K( P addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
* N5 n N- f" g' i* o8 j; K addrlen:sizeof(struct sockaddr_in)
9 O0 e6 M3 O1 ]# `# r4 C: ], a& J3 c ' Q8 ], s" ^/ x; j
6 send()7 }; D; C; c: u6 N _
头文件:$ m$ [% U& \" y! e0 e5 Z
#include <sys/socket.h>
. b, w4 p7 T6 m2 ?5 P% j8 ~# `1 g 函数原型:
+ l" C: A2 N! t int send(int sockfd, const void *msg, int len, int flags);1 C* i4 s+ E0 f5 e* z9 E8 D$ v/ T
sockfd:用来传输数据的socket描述符# P: v. y; Q: G- ]
msg:要发送数据的指针
. p, b5 ~6 t( Y, _% h0 f2 I flags: 0
6 D7 f6 H' E* f- B" B# { $ n8 s. b* V% B
7 recv(), B5 p$ x0 |4 v
头文件:
; w; T# j* f3 Z7 w% j" ^ #include <sys/types.h>' q" f5 @! J% J3 |! U( ^
#include <sys/socket.h>" e+ a' h" C: e: p* P, Y% W& [
函数原型:! u- {5 A5 ^6 O& [
int recv(int sockfd, void *buf, int len, unsigned int flags)
" i- V) b7 B0 N$ ]' F% r$ T sockfd:接收数据的socket描述符
6 C2 E# G1 y5 X buf:存放数据的缓冲区
1 D- R* F8 X0 q, C len:缓冲的长度( m3 j: M! Y6 f- c4 B
flags:0
9 @% Y7 ]- H2 r* U' a: m o, C$ R* S) a
8 sendto()( ?, c% W: m1 z$ A: }
头文件:
J4 N) h( a% V/ v. N #include <sys/types.h>% m0 z/ q2 x9 D5 Y4 P" U: m
#include <sys/socket.h>
2 r6 v$ b+ z6 p7 B5 j 函数原型:
0 P! E/ v! P: t) C) m+ S$ S6 w( I int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);& i4 f+ I# K# Y1 A# P
, ^5 X* e+ R; [7 u* S/ T' W / g5 ~" b( B+ |, N
9 recvfrom()
9 P5 p) J+ g$ j3 p: z) T6 Q& z 头文件:
: J' s* j+ J7 x& ]1 z+ R #include <sys/types.h>
& w+ H/ j4 O7 @) ^. n #include <sys/socket.h>" A- T6 k8 Z/ }1 t; g, ~
函数原型:
" E* I* Z4 b9 b0 ?, f7 v$ B int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)8 h$ D: ]+ w" A0 w. E f
& e) V9 O& l5 J& f$ D# t
6 e R% Y; A7 L( ` 10 read() write()
d9 t/ f3 Y3 r2 h# a3 {. b7 V int read(int fd, char *buf, int len)
9 @- A( U* o [ H6 e int write(int fd, char *buf, int len)
5 C/ X; U1 N1 |1 _) e$ O ~
5 |) N& M: w1 Z* j" n$ [ 11 shutdown()4 v% U+ v; n! ?$ a" Y
close(sockfd)
* Y: f, A# v" ~& d/ T( t int shutdown(int sockfd, int how)/ v5 Z/ g# m0 l+ |/ ]! F, Q: e
----------------------------------- [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等) 1 {( ^" M. \+ k5 o m
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等# m( }/ \: ^, r2 ]9 c6 W
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl(). T# N/ y; u d
<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等6 g4 m$ }* A# ~- H1 D
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等. S4 b4 t5 H: T \8 w- [' m
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
3 I' i+ S+ D% K W/ t4 f8 l; e5 w3 p<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件( N8 H" p" L3 d4 L+ H! L0 y" D
% F5 Z% v8 v: a% N7 E; ?
[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
& [% _/ d' v1 Y; x: D6 Z#include <sys/types.h>
2 \1 R7 F- _2 C0 C; V0 }5 E+ b7 }8 r( v
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons2 C4 o) V* k! g2 m$ x7 |* V
#include <poll.h> //poll,pollfd7 H' g7 z( }/ ~) p9 @6 O5 p
#include <arpa/inet.h> //inet_addr,inet_aton
' C; s+ q5 l, c8 H#include <unistd.h> //read,write' R" `! }! ^, J5 L
#include <netdb.h> //gethostbyname9 [" A2 [+ Q! h% N3 p
' T* F% z4 ` l& p) \5 e. l. r#include <error.h> //perror0 L9 I7 K ~2 ]2 }. \
#include <stdio.h>" o' K6 r* D+ `+ P' h
#include <errno.h> //errno
; |+ \! X$ \ }' ~1 q1 i* Z& A# |3 J+ Q' V! _
#include <string.h> // memset7 r6 r( S6 i0 l1 t; |( ]* k$ n- Q
#include <string>$ b5 i4 |1 K1 W0 i( o& F. k
#include <iostream>& W$ b" y4 a3 h( m" G+ X5 j4 {
9 R7 ?) J" d" X# j5 _$ U
|