|
[size=13.3333px]一 三种类型的套接字:
2 o6 B7 E$ d3 V8 ^1.流式套接字(SOCKET_STREAM)6 m8 j& e3 V3 ^. H( i7 @: F7 M" O
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。
3 d, I, [3 k" A7 v% n9 K2.数据报式套接字(SOCKET_DGRAM)4 K3 R3 [) i0 B" t
提供无连接的数据传输服务,不保证可靠性。* x5 ^# |4 ]: t8 h/ ]7 Z7 j* f
3.原始式套接字(SOCKET_RAW)
6 i9 Q/ T/ T' W6 I; B 该接口允许对较低层次协议,如IP,ICMP直接访问。" V/ u6 `2 l- d. _
+ ~6 t- b/ i) _( H9 u# \8 K( A# m二 基本套接字系统调有有如下一些:
! ?! s# K3 D6 w8 l$ Z 创建套接字: socket()
' c* W5 a9 p# B$ {! ]/ \ 绑定本机端口: bind()+ z; C' D3 r6 H0 z+ _
建立连接: connect(),accept()# h! h6 X) V0 g3 f: Q6 e7 l, k! U$ y
侦听端口: listen()' s$ S, s) ^, c5 U
数据传输: send(), recv()7 U$ E0 u: W/ m5 m3 ^5 o& Q
输入/输出多路复用: select()! p7 e3 d2 l9 x: p' X% E1 O" H
关闭套接只: closesocket()
4 q, Y$ f# j2 k5 J 0 \. G+ N+ @4 W3 p/ T2 |
三 数据类型
# D# c* R1 P9 N8 K1 P9 K- T struct sockaddr
( C" i. g9 m- M# {3 P+ l {
8 F4 d$ l! K* ^; g unsigned short sa_family; //地址族, 一般为AF_INET5 \0 K2 ^9 P6 {4 D4 f, R
char sa_data[14]; //14字节的协议地址
- l$ p% V* U4 \2 H; X/ w }* \% w' X& c% V7 M0 ?7 U2 ^
. s4 _7 Y6 u1 G1 G) L) J
struct sockaddr_in
0 L( q* G, @) [, ] {. I3 Q! v# R9 K% \5 h
short int sin_family; //地址族6 \* Y5 F- y2 I
unsigned short int sin_port; //端口号
+ s/ a/ J( A% S( B, T struct in_addr in_addr; //ip地址
# v* f2 l7 [, f unsigned char sin_zero[8]; //填充: M- w3 F5 \ g C0 J
}! ~0 k) `+ v4 `
4 ^/ ?1 S( L, ^- ^; q
四 常用函数
0 |$ a6 Y# @1 y# a* r 1 socket()" s1 z; Y$ h- Q' E( j3 d3 p( H/ w/ [. @
头文件: 6 e% J% g) {, d% t+ A p- P
#include <sys/types.h>
* S% r9 S1 ]9 O$ X: m# W #include <sys/socket.h>3 |$ |9 _) @/ x- m
函数原型:
@& B0 r4 T# V6 V; r int socket(int domain, int type, int protocol)) m# `1 `4 R; \& z- A; S
domain: 协议类型,一般为AF_INET
+ s% Z7 B& O% b+ v6 x4 O type: socket类型
+ `+ |/ m% q) ~ protocol:用来指定socket所使用的传输协议编号,通常设为0即可
5 u9 u8 g) M" b ~- k0 B' A! j4 R y: o: g" s, O
2 bind()
1 N* v/ s+ T* ^" p' _ 头文件:7 c3 O! D" s# K' E- R6 w8 s# q! m
#include <sys/types.h>0 N: G1 ~+ t3 ]% l6 o* O
#include <sys/socket.h>
& @7 e4 v* w# b8 h* p, | 函数原型:/ a: G9 B, O% Y- A: g
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)& ?2 p- [' i0 ]+ b
sockfd: socket描述符
/ r- \% R' C% n' ]4 g- `! m my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
, H. K5 d) a: o- p% n" R addrlen:常被设为sizeof(struct sockaddr)! {! S! n& l2 U6 b2 I9 P5 R& X* K H
r; R9 k4 |8 d6 R: f
3 connect()% u" C* Q4 | r3 N7 l* k9 [! F O
头文件:
+ L9 N6 G+ t" r. \5 d #include <sys/types.h>
8 V6 a/ e: f: C' c Q #include <sys/socket.h>
" ^! v1 B: M k1 T8 q( ?$ i9 J 函数原型:; ?& a4 W$ `7 p% t* Z# b+ J0 m; C6 H
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)1 o+ x( j3 M0 g+ m1 R4 }& a# ~0 p
sockfd: 目的服务器的socket描述符- g9 o' ^; f& H# d
serv_addr:包含目的机器ip地址和端口号的指针% Q. R/ Z% i8 A! G( K7 J O
addrlen:sizeof(struct sockaddr)
% q% C$ {" z. S0 m* \
% E. d; J+ o- P8 b! U% V/ ~1 k& k, L 4 listen()
7 y- C# h# {) s% @" h6 O6 G 头文件:2 Q, K& b- I* O) E) _8 X ^; k
#include <sys/socket.h>" u; z x; @' N" Z9 \ A/ e# B
函数原型:& D/ g, x t! j+ b. A E d' d
int listen(int sockfd, int backlog);
/ Z# u: l: X+ T: e, e0 i- r sockfd:socket()系统调用返回的socket描述符
# w% G3 H2 Y, G5 q backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。3 u: S: o8 ]1 l) t4 A+ U; @3 f! B& i1 c
# g8 I1 X* i* f& [3 O( U$ h: s/ {& x
5 accept()
. y5 {% }7 O: d- Z- K) ?7 D 头文件: , G: ]$ d& ^ ` Z5 z) b
#include <sys/types.h>3 |! V: c( D5 C; Z( D2 }+ c
#inlcude <sys/socket.h>& Z; L; h- F4 O. y
函数原型:
5 [, L1 q2 f8 Q' G5 ]5 Q Y int accept(int sockfd, void *addr, int addrlen)
( H8 g1 Z! n7 G7 | sockfd:是被监听的socket描述符9 E9 G: U. ?- o) ?0 j5 R
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息) M7 z$ j3 r5 l6 T% v
addrlen:sizeof(struct sockaddr_in)2 B2 c( x7 e! z# a/ X
2 I* f: i! v' Z6 [6 V! B9 ~" r
6 send()9 {4 j+ L3 ?! o; d5 Z. D/ f
头文件:0 |. v* {4 _$ s! c$ D: t
#include <sys/socket.h>: i s8 A8 p# H y. d# A0 T) F
函数原型:
8 I2 i% B% Z* Q S8 E! u4 F int send(int sockfd, const void *msg, int len, int flags);& E/ c& F c* h
sockfd:用来传输数据的socket描述符! @0 O+ L' H0 {8 @' k" E
msg:要发送数据的指针
8 y3 I G; K$ T" q# u. c" F flags: 0
9 y- u2 h: {- K9 I 7 i% N O; U" }* i, Z# X! l
7 recv()/ s( i2 q& g) E z
头文件:
6 f4 W; [8 ^: B- s! W( ] #include <sys/types.h>6 p# a" d& U6 C9 J' f& ^& Z- E) I) A
#include <sys/socket.h>/ @( T' [ ?8 t7 z! m! \, O! ^
函数原型:5 y, l+ M9 e: R- N! N5 g' h
int recv(int sockfd, void *buf, int len, unsigned int flags)! ^ W, a6 G" @' r, L( Z
sockfd:接收数据的socket描述符
& Y: f* ]8 }; P: C$ A% z buf:存放数据的缓冲区
; n! m u# M2 V) @) N; k* G len:缓冲的长度$ V+ o7 t# ^& E' g4 o! s1 O
flags:0; N- l% Y& {, Q: L2 Y
9 H9 V1 ^# u, R& Y5 k* C 8 sendto()+ g; W. i D2 X4 V8 [+ R* V
头文件:; x& x: g3 o9 u$ o3 ~. F
#include <sys/types.h>
1 L6 e; k0 \1 u* }# G #include <sys/socket.h>) M6 {8 G6 z0 m1 u, a/ L' k8 h, R
函数原型:, D/ h5 z' t) y8 W5 k- ]. D
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
& K9 g% q9 Y; r& l7 m$ G/ g4 `1 T 4 x5 |! S- _! L& P
5 }/ A0 [" v6 \7 w 9 recvfrom() O# R, P: p" Y7 x& G- Z1 E
头文件:
2 ]$ g& }5 S2 @ #include <sys/types.h>
8 B2 A- L1 l3 ? J1 y #include <sys/socket.h>' r+ m% f' G; s. Q
函数原型:$ W: F/ i4 Q2 d5 ]2 e& C
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)5 j1 Z; L6 b- Q( R+ K" A
7 m# n* l) S9 Q8 v. O$ G5 R5 v; Q
8 T) I- E9 w; X' ~5 i1 P
10 read() write()
+ f4 M) i% I7 p int read(int fd, char *buf, int len)$ U/ d' _. c2 v# O6 b$ Q3 [
int write(int fd, char *buf, int len)* n8 r& P$ M+ A2 c4 A: h# ]: H+ I7 O
1 ]/ [3 C X9 C% k4 C; [" d* ~1 m
11 shutdown()7 p; T% I3 x7 x/ H
close(sockfd)! N& B# S- f; g
int shutdown(int sockfd, int how)
( @8 _# [4 q/ K. D----------------------------------- [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等)
; [( t( m7 R p/ ]6 I<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等/ I H V* x+ h% T4 w
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
6 n4 t# {& p+ J<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等( y5 ]9 F3 p5 u6 H
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等! y' C1 G" |% p5 R0 E3 }
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
7 ~5 r0 t% L$ o4 j<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
+ ?, j$ m3 E. c& Y. M" t
/ J" }% ]' h+ K0 O7 ~/ v6 `6 m[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等1 K& Z: h$ z: D: ] K. w; U; N- G- h- d
#include <sys/types.h> + t+ z+ B0 }. {4 L
" r# s* n5 k" G#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
$ H1 d4 i% [* E- K r8 T#include <poll.h> //poll,pollfd; P/ ~7 h' N- `. Y( U/ R5 b- Z3 E
#include <arpa/inet.h> //inet_addr,inet_aton9 h1 }, s5 R9 G3 W
#include <unistd.h> //read,write/ C6 W; i2 f, g
#include <netdb.h> //gethostbyname
- h: P1 W; {; k
* v/ D( B9 e" ^1 j J' h9 m8 ^2 M#include <error.h> //perror' k% i8 \, K. c- g. k: N' I. R
#include <stdio.h>; ?9 q$ R7 B# L- y: ]/ \
#include <errno.h> //errno
1 c/ O# K: w: [/ `/ m0 H6 x I' X4 e% R, P" M; a: G" R6 k
#include <string.h> // memset; { a0 M0 M5 ~+ M2 o/ P
#include <string>
/ y0 l( c) y: z8 h8 U#include <iostream>
4 |$ S4 h5 c7 J' |4 s6 M+ K
# A: E3 {5 x! n$ |1 e |