|
[size=13.3333px]一 三种类型的套接字:
( ]0 d0 H$ A4 _. G, M5 ^1.流式套接字(SOCKET_STREAM), F+ N' t' o: s* ?
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。* C s7 g1 j# d( J" o4 @" W
2.数据报式套接字(SOCKET_DGRAM)
# J3 b$ e' [. Z 提供无连接的数据传输服务,不保证可靠性。, Q; N4 c1 ]0 x1 R) w9 V: a
3.原始式套接字(SOCKET_RAW)( S/ C& a3 N; `1 A: z% j; E
该接口允许对较低层次协议,如IP,ICMP直接访问。" ~! T3 m! ~( z! D* ` p) t, u
. u7 C. ]7 S9 i/ k* {3 J! F# t9 s9 M) c# n二 基本套接字系统调有有如下一些:) x. N5 I9 R- P6 \
创建套接字: socket() a& p0 k8 x# T
绑定本机端口: bind()
3 b" }5 ~1 E( R 建立连接: connect(),accept()1 G7 W# [& I7 ^$ M7 ^* T- H- J3 Z6 l
侦听端口: listen()3 b8 _& N& I' A- R% b3 g
数据传输: send(), recv()4 L# k0 t0 ^) C8 T, p
输入/输出多路复用: select()
2 c' x$ t9 o! s$ {/ e: e/ C 关闭套接只: closesocket()
3 K7 E7 b; X" |" Q
. @9 I- b1 w* U$ r, A7 ~三 数据类型2 @$ p e4 }, @- F# R7 ?! P& X
struct sockaddr3 Q ?! y& I" T$ P+ K6 P
{
" g, o1 P$ c* l T( v unsigned short sa_family; //地址族, 一般为AF_INET6 t4 z4 X# e5 V. z/ U# @5 ]
char sa_data[14]; //14字节的协议地址. u; H! Q( f2 }
}
' @5 {7 ~7 d8 c) i1 Z+ y" t. g% P2 r; @' {) R6 J! J
struct sockaddr_in( x; N( O% r/ M9 {4 |3 \- i
{
) @/ ~7 [: W8 l short int sin_family; //地址族! a9 w1 m3 K$ w3 y/ @
unsigned short int sin_port; //端口号
, X2 Y1 k5 y8 V) p, | @ struct in_addr in_addr; //ip地址
4 t. Y1 F: x6 ~7 I2 ? unsigned char sin_zero[8]; //填充: I3 V2 f0 |" |/ K' O
}; H2 o# s1 v+ Z% V$ L! x
, V( K0 ^) N# {' f" G$ k5 ~. g四 常用函数
' F( ^1 T5 W p- G8 G5 }( N/ V 1 socket()
' z2 b5 ^4 `. e) b) B# m 头文件:
: Z7 e5 o: M( Z #include <sys/types.h>4 [- p# s* J7 A& I) x, ]
#include <sys/socket.h>
1 y! @6 {7 @4 c0 h, M 函数原型:* I7 c( j& z! V- f/ {
int socket(int domain, int type, int protocol)
% ~. [$ W W- S# f6 e$ o" D1 U domain: 协议类型,一般为AF_INET
' {% {- S& \0 Z, L% x# O { type: socket类型. ]8 z. \0 |! T3 h* T! k9 O
protocol:用来指定socket所使用的传输协议编号,通常设为0即可$ Y; {. t0 O, h' \) y" @( P
+ S) x8 c* ?$ c) M+ a, Y P1 m 2 bind()
% Z9 m$ {8 \6 i 头文件:6 Z% E9 f9 F" E- W6 T
#include <sys/types.h>. i6 ~# t8 q" g
#include <sys/socket.h>
; {. E7 e; q; D, p 函数原型:- h* `, g0 r. k8 L
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)8 h" f8 D+ C9 F( ?8 D5 s
sockfd: socket描述符0 S" n I5 D2 j9 u: h
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
6 }" H5 m+ _& } addrlen:常被设为sizeof(struct sockaddr)' _0 \# `, M2 l, v' n- l
+ E* Y& C2 A5 u! s
3 connect()
& M2 q+ Q) O9 H# E. w! R 头文件:/ d. k5 o& V# @" S6 v2 n4 B8 J: U. K
#include <sys/types.h> 7 k B6 D3 v6 P$ P9 F& z% X3 A
#include <sys/socket.h>( i I* ~% L& q9 Q) Z# S
函数原型:! o* P1 [( d& b {+ C3 d6 e
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)6 I$ B9 N/ L+ k9 q
sockfd: 目的服务器的socket描述符4 i; i+ q: J% e% ?* I3 P+ n8 G
serv_addr:包含目的机器ip地址和端口号的指针
. c/ m1 X# w5 r/ e6 H1 i6 ]; Q( B addrlen:sizeof(struct sockaddr)
9 ^3 F: f$ D2 z3 A9 N1 [/ t: f! O: M$ h8 W8 R
4 listen()
' r, y; a" c0 _ o H 头文件:9 p! t3 R! M: \. c$ k
#include <sys/socket.h>
: m; p5 \, g/ E) [( C# @, N 函数原型:* v, R, h5 P# X, J' ~" l
int listen(int sockfd, int backlog);
, j+ o* k( z3 r0 c) B% { sockfd:socket()系统调用返回的socket描述符/ `' s: M( C `2 g+ \3 S
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。) O/ B8 c" t/ @. p
# ~0 r! ~2 I; w c
5 accept()2 l5 I6 W7 c1 v% w7 v
头文件: 3 x+ G4 \- o; g/ A J! M
#include <sys/types.h>
. n, c9 }& I4 Q& j' E& i1 z #inlcude <sys/socket.h>* p; Y) o4 p8 C8 R! e. P7 u
函数原型:
5 k( X% A, {) h& X/ J* u: G# X+ f& p int accept(int sockfd, void *addr, int addrlen)7 a; L9 D% p$ L {3 \+ e
sockfd:是被监听的socket描述符# `0 l9 k+ B. \5 @# X. h* O1 k6 M8 k
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息+ w$ o2 V; j9 W* R4 ^) Q
addrlen:sizeof(struct sockaddr_in)
- a9 {! k4 x1 X8 W0 x% e, L 6 Q* n3 V& l' a3 ~ t, K w
6 send()
4 q$ J8 {: N, u8 p# H8 Z 头文件:5 `) J9 Y" h5 ?6 r
#include <sys/socket.h>, m e+ b" y# I9 F- Y
函数原型:
9 y5 I/ [ {- o int send(int sockfd, const void *msg, int len, int flags);+ H" g! ?9 H+ r2 X: b; k8 ~# a+ R
sockfd:用来传输数据的socket描述符
" d7 }7 X- S' |9 N0 W+ ~% u! E: w msg:要发送数据的指针
4 U* f5 |$ r" A, V flags: 0
& d, m8 A' l, p, Z/ o
/ n6 S! O4 T; N( s& C# F" ~ 7 recv()5 \4 b8 i! R( H! Q5 \; u
头文件:
5 o5 H- T( J' I #include <sys/types.h>
7 Z) y, n: B4 v7 b. B/ Z) Q #include <sys/socket.h>' H; k5 V, m: v5 a: Q
函数原型:4 P- ^4 ]- V* M' V4 |
int recv(int sockfd, void *buf, int len, unsigned int flags)
' ]1 z0 Y! D8 d, m, F) i sockfd:接收数据的socket描述符* r! @6 M/ |1 _+ ~' z
buf:存放数据的缓冲区
# _1 b3 a T+ A& g' m len:缓冲的长度
5 [- l% x- P8 U0 l# I flags:0+ }9 k" k: d' |: `% j" S$ N& z
8 T+ T) X( ?. {8 J0 j! r
8 sendto()6 H1 O3 T% J7 F4 m) z U2 O9 u
头文件:, h. f, q. p+ h9 Q2 e9 B. Z
#include <sys/types.h>
% @ p2 b$ ]( r8 Q- g5 U0 d1 b #include <sys/socket.h>
0 i3 }2 i# S d z# X 函数原型:
1 F# I' m* ~' S* u int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
# y* g9 h5 W7 Y8 D4 P- V
* S8 L# v: c4 J1 p - I# Y. p, N# a7 Z6 b
9 recvfrom()
7 k) L; q# v& w8 A 头文件:
+ Y+ r- w# U0 ]& \* r #include <sys/types.h>
' Y/ N! |" e* Y( r% y' q. t #include <sys/socket.h>
. L, ]9 Y! p4 A& e 函数原型:# H7 Z" g! M& K6 c' p
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
1 R# U- \9 t* v1 b! ^% x( ]" |* j( P4 b: c* w, f
1 U" o. G3 |: {, \
10 read() write() Y, o) s" O2 A0 U4 g; K/ x
int read(int fd, char *buf, int len)
W$ |& \0 N# c; d6 a: u int write(int fd, char *buf, int len), j( v s9 r, G
7 Y! w* p. D& e6 @5 }
11 shutdown()9 H& X0 `7 y0 S, e
close(sockfd)+ g8 @, x( K4 ]# x
int shutdown(int sockfd, int how)6 J# h3 I6 O6 N5 T% 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等) 7 ^( W1 }* p5 u4 q, z4 r4 V
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等5 E1 D" ]6 y# S- v( B4 R( Z
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
$ K) p( G/ c$ a+ `<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等& N* B2 N# X- q5 M2 j
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等- F% a7 ]+ X0 D
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
0 j W& w& G4 z<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
7 U3 F! G( J3 M8 w N h7 r' f w! k
. n5 ?4 ^& ?$ Z. D[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
8 ]* L# `/ c1 ?6 K( Y! O6 M#include <sys/types.h>
5 M+ `1 n( G# g* M! C9 E7 `# C! k5 w* y/ U/ v/ e
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
7 T! }4 p t' K6 Z; b( V#include <poll.h> //poll,pollfd: K$ Z7 @) z3 @; I0 O. w: f
#include <arpa/inet.h> //inet_addr,inet_aton) B6 w2 `2 C; p
#include <unistd.h> //read,write4 Y* u+ k j* x9 I
#include <netdb.h> //gethostbyname: V7 O0 |$ D/ N6 h' @
* |* {% B0 U. a. ~/ e7 w0 R6 E
#include <error.h> //perror$ W* G$ C3 h. Q* b3 m+ G( C; _
#include <stdio.h>" y$ `+ {! K- I* l0 l
#include <errno.h> //errno
7 N; x) }8 Y4 Y4 h0 w8 b+ L4 c+ e |( `- |6 R" O$ B. G/ k
#include <string.h> // memset
+ P9 U5 b7 S3 c C; N0 q' h$ V3 M7 R#include <string>7 G6 h& m1 _4 [, i _$ |
#include <iostream>! ^7 M+ P/ I- C
# P* A( u+ l. j; s
|