|
[size=13.3333px]一 三种类型的套接字:# H: j' G' _4 w) m* M
1.流式套接字(SOCKET_STREAM)
0 T& F2 n! U4 ] 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。
/ ]8 K7 z0 S6 N# G2.数据报式套接字(SOCKET_DGRAM)
( x$ k7 `9 Y8 [. L+ m 提供无连接的数据传输服务,不保证可靠性。
* u2 o( h0 d4 E- i3.原始式套接字(SOCKET_RAW)
" }9 M0 u- @2 G+ c; O 该接口允许对较低层次协议,如IP,ICMP直接访问。( I2 y, Z$ Q& ]+ ?, W2 Q
1 {- i, I! K3 f3 ?/ r. m二 基本套接字系统调有有如下一些:- b/ l6 M1 d: |1 G( l
创建套接字: socket()" h5 i7 V8 P' D
绑定本机端口: bind()
1 z: S. q- q2 P8 e. Y( X 建立连接: connect(),accept(): B: K$ M/ ]% j2 P7 ?2 F
侦听端口: listen()
* s' L/ T. ?0 _8 q. B# x 数据传输: send(), recv()3 X% S$ ?/ V, t' s+ `. E$ g
输入/输出多路复用: select()
1 w6 ?3 S6 M2 N 关闭套接只: closesocket()3 w& ?# L) O2 {: l" [* {2 b: p
" A% f. H7 p) M! f# t7 b三 数据类型
8 H/ t" x9 K# X W struct sockaddr! s, f- s6 L. \& _) L
{
* n- C" s- x Y" Z; h) I; j unsigned short sa_family; //地址族, 一般为AF_INET# n1 Y g# N O- B1 o
char sa_data[14]; //14字节的协议地址
) \7 ]8 T& i( e6 @- a }
6 G( g3 J- Z+ s2 K- T% {7 U( L, T% G. S) j1 J' d
struct sockaddr_in
; B/ w% N+ ?8 [% a) I {! ]4 E5 f x3 X/ L
short int sin_family; //地址族
8 c' o$ M/ O% \; \ unsigned short int sin_port; //端口号
* i ~7 J8 ?, t, [& W struct in_addr in_addr; //ip地址, E, G& g/ K" W& [1 A$ f/ w
unsigned char sin_zero[8]; //填充 f4 Q' i" m# p; t/ H
}
1 ?0 S) G" w" O- U3 a( \0 X" \& {. I# i; j- I% _; p3 r( |( ]
四 常用函数9 K! o5 _/ G7 I: s
1 socket()
. k) ~( H2 y2 B6 A. ~' W$ f 头文件:
" m3 O, A1 z6 G #include <sys/types.h>5 y5 r8 X2 l" m4 h* A
#include <sys/socket.h>
& z" X. \4 ?$ y9 S- y9 r) T 函数原型:
: Q5 z1 C: _" X, ]; v& | int socket(int domain, int type, int protocol)
0 s( } I/ R7 U- X3 t; _" S domain: 协议类型,一般为AF_INET, A& Q. m2 w. Q5 f" q
type: socket类型
" j+ e6 P7 F% d- P6 a4 v protocol:用来指定socket所使用的传输协议编号,通常设为0即可
; h( I0 F, }* q4 }
" U9 [( V/ \2 b" ?2 J 2 bind()
; q! @) r; a# v' E' L 头文件:
/ v7 C$ J4 W4 d( H #include <sys/types.h>3 ~/ Y x4 }0 e! h% m3 |0 J1 o3 s
#include <sys/socket.h>0 p. K) n' w7 Q
函数原型:
# Z7 S; R' C* W X. `+ ~ int bind(int sockfd, struct sockaddr *my_addr, int addrlen)7 I+ k' F2 e |8 g" o; Y
sockfd: socket描述符1 Z) Z) X0 h$ r6 {& T. S
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
, q( |+ A4 M, n4 L/ v- n) D addrlen:常被设为sizeof(struct sockaddr)2 d- ]# p' Y' Y6 f4 P' T
; e) Y ^% C* \% L! n o% j 3 connect()& a! w' q- W: ^" F* T
头文件:3 m: w' w8 o6 ?/ M9 T6 X& H0 e
#include <sys/types.h>
; }3 V6 D. m% J #include <sys/socket.h>
2 x: I( _: L9 N% L- t T 函数原型:
$ |, N& }$ Z8 ? int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
# B7 s% S# B* J+ ]1 O sockfd: 目的服务器的socket描述符4 n+ S4 W. U8 F- A$ x; V$ V
serv_addr:包含目的机器ip地址和端口号的指针
) A) L f% z% [( k, x3 t8 L addrlen:sizeof(struct sockaddr), ]$ ? u: Y& u! {
/ S& Z* ^5 g3 _& C! a. ~
4 listen()( ]0 I3 r5 J1 o6 j o+ l4 C
头文件: o! f7 Q6 ?- r4 w( `
#include <sys/socket.h>. l% Q) s5 E. f; k
函数原型:4 W# O. l0 R) [. K5 }$ h7 t
int listen(int sockfd, int backlog);) L* T1 ?, y5 s, I
sockfd:socket()系统调用返回的socket描述符7 f6 @7 Z% m: Y, g0 H6 H) x- s9 C
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
+ k* t( ?+ r& Z) Y: a2 t r8 u6 u5 e/ `* F" s
5 accept()7 F& s- G+ D$ o2 p' R: J
头文件:
; r; m$ P9 y6 x: i0 i4 x, d8 J* q #include <sys/types.h>
$ o) J. \7 j( F- Q #inlcude <sys/socket.h>0 n# A g4 d' L; x# O6 v
函数原型:% ?+ V2 }' J# }* O) R9 ]. k5 M
int accept(int sockfd, void *addr, int addrlen)
|3 s- a# _6 ] sockfd:是被监听的socket描述符
7 N! C) P9 R% h0 t& ?; p9 j addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息) { @& x; k$ v6 K$ g$ X1 p
addrlen:sizeof(struct sockaddr_in)$ ]9 h& L* I7 G
/ }: l4 |. F1 r% \( ]$ W0 b- } 6 send()
5 v! d' i1 l. @- c 头文件:0 h Z5 O8 f+ S K: R
#include <sys/socket.h>& S% ]$ X- U$ _8 M9 N' i7 o6 o
函数原型:
9 a, y. r9 I# @- d int send(int sockfd, const void *msg, int len, int flags);. g7 q+ R3 `1 v8 y# H8 e% e
sockfd:用来传输数据的socket描述符# W1 v p8 Y+ m
msg:要发送数据的指针
3 P6 X# S" m" L" l" T flags: 06 H$ k! a- r% h" D6 Q
~+ g2 u% K D. d3 b- l8 l! |- A7 ~ 7 recv()
" i+ | ?0 T9 m 头文件:
5 W X- N; l- t' {( X9 y# C #include <sys/types.h>5 y. i$ k( B* S' ?+ |8 S# ^* [
#include <sys/socket.h>0 _/ y% |* _" W2 G1 r1 X7 A" Z- R
函数原型:
( j( A i' X$ N# N: t ~ int recv(int sockfd, void *buf, int len, unsigned int flags)5 {/ e. t }5 I
sockfd:接收数据的socket描述符; l! s; x: i% i( j/ a C& Q
buf:存放数据的缓冲区
/ ^) ^% {- P: u( j2 o len:缓冲的长度$ A0 Y# T! x+ b7 W
flags:03 X# y5 b% ]3 R% i/ v9 k
5 V7 X, l: P6 m
8 sendto()8 d* h, K, T! Y3 g$ k9 _; Y
头文件:. K' m) c6 s" r% q b, x4 J, R
#include <sys/types.h>
/ @1 r/ |* `, {. Q5 k7 s9 @ #include <sys/socket.h>! V; p H5 ] K! t2 w2 o" I
函数原型:
( @6 } J9 S; N& Y" g int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);6 w+ I+ {/ X6 @" V( ?( j2 h! O
! C$ G# ?6 O$ u3 B5 l8 Y! r W6 s7 q2 ^
2 @- Y$ `& ]! J# S$ W* f
9 recvfrom()
9 O2 C$ x: l* D 头文件:7 f8 B: n6 v1 L
#include <sys/types.h>- L$ t. C& ^4 r, N; D' c2 p8 |, F
#include <sys/socket.h>! m5 z6 U) j* M' I4 I5 d' M
函数原型:1 q1 @ J2 l0 _3 X" f3 b
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
8 f# ^9 V/ p2 v0 B' `7 Q( Y) w1 O3 L, C, k
4 i& R0 m" k& j) v/ s7 c 10 read() write()
8 `/ g+ Q' r/ S: c. u int read(int fd, char *buf, int len)
) m" A5 e8 k8 H( B, G' u int write(int fd, char *buf, int len)% _; _4 c$ N1 \5 Y0 t1 b1 J
5 a) M2 }$ L. h0 F
11 shutdown()
- F3 Q+ @. b3 Q, Q2 e$ R5 ]* |# B close(sockfd)5 `9 ?$ }9 }+ C1 n Y( s7 e
int shutdown(int sockfd, int how)
0 a* n# u1 d. H----------------------------------- [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等) . L0 @, [, ?" G. _
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等5 u& _& a' t( x3 R; r$ Q: o" Q5 d
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
4 C, c& F I& }7 y<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
0 @2 U) c1 Y& F U7 p9 b. K<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等6 y5 H. D: ?) q5 K: A5 h
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
$ `1 e) A; W5 K<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
( O; h. u8 B) m/ y
/ I5 d; [9 ?3 n1 n8 @[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
( w7 p5 X+ q/ b5 _" ~" ?7 E7 h3 k z#include <sys/types.h> # \0 V% O X7 K5 s% e8 }
, T- K' l" z3 A
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons) V- p5 ?! a9 n# C6 F
#include <poll.h> //poll,pollfd
! ]+ p6 w1 _5 R( u$ t#include <arpa/inet.h> //inet_addr,inet_aton
5 w7 V( Z# e ?2 ~1 h" z( ]0 T#include <unistd.h> //read,write
' [% {+ h1 n4 E+ v#include <netdb.h> //gethostbyname
1 t+ L, `9 V2 R7 r. I
& D9 E1 N, s* S0 C, ~; q6 `8 H#include <error.h> //perror- w8 h1 D( G! l
#include <stdio.h>$ m5 }8 C! f6 N% h. g& B
#include <errno.h> //errno
6 }0 N2 t: g% j5 t0 e# P
* T+ `, [+ f' Y1 ?#include <string.h> // memset
' Z. L, ^& N# {1 w" n: a4 _8 j7 s0 n3 m8 W#include <string>- F+ Z, F. ]2 W0 v& x; H! y
#include <iostream>
1 q' x g$ s8 Y4 o: ^! E2 T& a$ K) u* ~; R
|