[size=13.3333px]一 三种类型的套接字:
( P; l+ Y t0 V7 L, c g" F1.流式套接字(SOCKET_STREAM)7 d3 C& C7 l3 {+ z0 k
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。+ n% q: _! x4 Y. i( ]2 l
2.数据报式套接字(SOCKET_DGRAM)) d3 s6 |' d& ^
提供无连接的数据传输服务,不保证可靠性。
5 z. [) g% ]2 u. w- g3.原始式套接字(SOCKET_RAW)) Y0 s+ {7 ?1 c9 V: G6 U4 X) k( v
该接口允许对较低层次协议,如IP,ICMP直接访问。
$ {7 `' l Y- S' c
8 N t" P" o( ^# R二 基本套接字系统调有有如下一些:
* q; R; k( j6 ?2 E 创建套接字: socket()7 J# w7 t7 p5 N5 @& v: n1 A
绑定本机端口: bind()$ Z2 v; @ k" W2 X
建立连接: connect(),accept()# ^# `" E8 g& _: T, z6 T
侦听端口: listen()
# K- ]% q' K- l 数据传输: send(), recv() t4 `- R: p# B& @8 ?
输入/输出多路复用: select()
4 u- V* N) Q+ _" ]) a 关闭套接只: closesocket()' D4 F1 O$ v1 [/ V
# a6 P* f4 t, U: Z2 z7 u' D9 H p2 E三 数据类型8 F. |. g: h7 N5 L& f9 l
struct sockaddr
* Z1 i2 L) r! A$ z% Z- x" c {
7 F, ^5 n$ @2 [! W4 m' S unsigned short sa_family; //地址族, 一般为AF_INET! j- h, Y& e, f% k- z& P
char sa_data[14]; //14字节的协议地址
- X$ H8 L- Y. {1 M5 h }6 `: J9 H3 T0 d: U
( x% l1 S: G& x% `
struct sockaddr_in, ~5 s* ~5 U" T% i$ z
{/ a0 a& G! g) S, U6 w6 `
short int sin_family; //地址族
: ]: H# b) g0 } unsigned short int sin_port; //端口号
( w& c r" r5 I2 K( J6 O: L. ` struct in_addr in_addr; //ip地址
" N9 v+ K q5 N unsigned char sin_zero[8]; //填充
( D3 v5 e- d9 a: }; H }
* Y% { ^5 r3 B0 x3 H: s3 L: h1 b0 r3 Y* ^& `% u' T+ k9 d, v
四 常用函数
% O% X6 I. V/ j1 ^1 `0 R6 J 1 socket()
- r' `2 {9 G6 @+ h; H% ^7 }( z 头文件:
2 U- s* t) d n3 y+ r! b #include <sys/types.h>; V: f" h) C+ O$ d' X. \9 x& K e
#include <sys/socket.h>5 I1 l4 u* q$ j5 s6 C! K3 }! H: r) p
函数原型:( o5 t# l' n4 U' \- P2 e
int socket(int domain, int type, int protocol): O: l$ z$ a. ]" f
domain: 协议类型,一般为AF_INET7 b8 k7 r, G( [# m% R6 v( |
type: socket类型3 l, G0 _ F5 q4 E& j( i6 A/ L* X
protocol:用来指定socket所使用的传输协议编号,通常设为0即可& a1 _6 |% E5 T) o" X6 q
& S: V+ U) t. w# M6 s" V' B) O 2 bind()
! s O" ?$ ?* R9 m 头文件:
- ?1 k0 @5 E- P* L #include <sys/types.h>- d8 a& A8 K, L8 A0 T/ T8 v
#include <sys/socket.h>
0 h! K5 h; L4 B0 h9 o$ r0 A 函数原型:
5 v. ~# u4 Y9 u int bind(int sockfd, struct sockaddr *my_addr, int addrlen)( N) x b( Z4 A3 N
sockfd: socket描述符
! m. m" [' Q" L- h0 O2 q6 l my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针$ h; |4 q" }( \6 O7 H
addrlen:常被设为sizeof(struct sockaddr): [3 D. V# ]: t# q! h: m
( ]( C- D0 d& g |% c 3 connect()
+ t4 d% b" p _7 t; ?0 L/ j 头文件:
4 L' T/ S) @4 M #include <sys/types.h>
. r( l6 G( M7 F- o #include <sys/socket.h>- W! \( y" x' I. M9 @; D- p
函数原型:4 i) a" z3 C- g V0 |2 Y# `! g" E/ s
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
5 E2 O( T" i9 I: {: e5 ? sockfd: 目的服务器的socket描述符
6 ^! y) T2 S: u0 X( i2 ?% L serv_addr:包含目的机器ip地址和端口号的指针& X6 Y+ f+ \% P1 |- u5 n4 B6 \
addrlen:sizeof(struct sockaddr)' n5 |/ A. [* t/ F/ b
5 `3 n3 T* O6 S ^
4 listen()0 W; S7 g `- h+ U' X, o, E @* x6 u
头文件:
. x6 `* C' K C. V3 Y #include <sys/socket.h>4 G3 c* Q' J* ~- W) [
函数原型:' P/ k- M. I) ]) l) _1 b/ G
int listen(int sockfd, int backlog);! Q% x# j/ J9 `/ C
sockfd:socket()系统调用返回的socket描述符
, w5 ~% c4 N" w$ H6 S; q9 _5 Z backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
) j* R; T; K, ]- Q, }1 j5 C5 ?2 H X
5 accept()7 {: |+ G& ]& }3 |9 {' ~; s& p
头文件: 5 N7 @$ l: V+ \
#include <sys/types.h>
3 q& V' {: \# I; |, p+ L- \( t9 } #inlcude <sys/socket.h>
" U, k* x1 T/ a+ a7 s/ c 函数原型:
" p4 h2 `1 u9 n. g3 C3 \4 }( Y4 G2 A int accept(int sockfd, void *addr, int addrlen)1 g$ [+ D8 D& `$ m9 F h1 x/ i
sockfd:是被监听的socket描述符# \& u0 ~9 n+ J" K p! K) Z
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
* k6 X# J& x$ [3 O& J$ N addrlen:sizeof(struct sockaddr_in)/ C) b4 h: u! J, u- I- W
& V7 |. w$ n, D T' s% X
6 send()) D) J: ? `7 T. Z1 r/ Y
头文件: p, k: i- J+ s, V* [" J
#include <sys/socket.h>5 N3 A; ?( W8 y- f8 J
函数原型: Q9 j3 ?; f/ r: Q7 G
int send(int sockfd, const void *msg, int len, int flags);4 ^: ?1 P# K& m9 o3 p
sockfd:用来传输数据的socket描述符
! o. g$ |! g0 i; M5 `! @- @ msg:要发送数据的指针 0 U5 N' y' I6 o S+ U
flags: 0
- m& s X2 f$ q3 F0 N * [ @& W3 [" ]! d
7 recv()' S4 `9 R4 ]2 @7 p v+ p7 M/ |
头文件:, b. h) J5 U* ~ Y" V( s
#include <sys/types.h>
) n7 g1 A. L( k. f #include <sys/socket.h>
& I4 ` _% \' L( _/ @ 函数原型:5 w0 J. G7 U' X1 D1 @
int recv(int sockfd, void *buf, int len, unsigned int flags)
$ }; P8 ~" R% i' `, C( h* D9 L' U sockfd:接收数据的socket描述符
8 D$ f1 b4 K9 R2 B7 L- } buf:存放数据的缓冲区/ x! D& b/ ]* {8 j( J' W0 M1 u
len:缓冲的长度 d0 j' G% N/ O2 z4 s3 o
flags:0
1 R# c& T" `% E* O- B6 r/ `# t( j2 @6 E4 ]# F6 N8 g( J5 t
8 sendto()
8 z. Q$ h- W% \' {: @ 头文件:% V, Q8 Q( {& Y* }/ o
#include <sys/types.h>( P' X, [8 }; L9 M$ T
#include <sys/socket.h>' s/ p/ Y6 s- ?) T
函数原型:5 Z* ]6 X. t0 u+ l8 q
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
' b4 W1 [) r' M% _ " X: [: K9 K# _5 s6 H6 J: Y9 }
7 G( p! ~* ^, T" Y2 B
9 recvfrom()' c1 Y$ w( Z# F: Q) C4 }3 S
头文件:! s, l& a6 t2 Y/ J& E/ ?! P
#include <sys/types.h>/ o! V2 ]- F% [- x
#include <sys/socket.h>, b0 C. p ?; d3 P8 v
函数原型:
/ A, J2 g' G3 n$ W. W) X0 l y int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
$ n$ V3 N" ^: p$ T( E4 w! ~+ ^' W' O* Z" ^4 |6 F/ t* M/ I" \
( ]7 L, `( w; f! d: t& F( s
10 read() write(): T* Z8 `- N3 p; H5 B, ^* H/ G2 O
int read(int fd, char *buf, int len)4 E! c" s$ R5 D( B1 y4 ~1 c
int write(int fd, char *buf, int len)
7 d% x8 [) |- `( c/ v# k 3 F* U3 C \/ D& [6 k Q
11 shutdown()) R/ d' L6 v6 m' `7 f" Z. X
close(sockfd)
; @, P' x4 b4 K! S( N- ~ int shutdown(int sockfd, int how)
% d$ U- F5 K( Z# C& k# G; ~3 W----------------------------------- [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等) + J3 [2 J/ D9 _0 j9 j" }$ I
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等
; q- Q) @8 R; n2 P, p9 b) m$ r( X<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
7 _0 P$ J5 e1 b7 {+ O<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等" I. U* U1 L4 x9 v
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
- D# w0 ?7 [2 [: x3 T4 h<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
9 k3 y9 @7 c* q; N7 i* ^<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件! \$ K5 x/ O( A1 n3 k
2 [- L+ L/ p8 N1 H[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
6 s0 h6 J1 \/ {( l0 s8 v3 E* r4 D; I#include <sys/types.h>
, Y# J, v* G1 i J, o/ _# g% M
) [0 C2 p9 p0 g" N3 @: t4 U#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
; f9 L: c/ {- r) T/ z1 E& o4 I0 j#include <poll.h> //poll,pollfd
/ W6 Y {: I: n2 s#include <arpa/inet.h> //inet_addr,inet_aton" G) e) f3 Z9 d+ K( `
#include <unistd.h> //read,write0 D- i5 L2 R, M& ?
#include <netdb.h> //gethostbyname
1 T$ E& }6 l' V2 y' D A. a4 [9 y
* }4 z9 l7 L4 [: M/ t#include <error.h> //perror
5 @; C9 {/ M7 D# q4 N4 s# K4 q#include <stdio.h>/ N3 [0 q% D, ?! V- _
#include <errno.h> //errno
7 w- I. c4 z% {! ~3 z( b% F2 O
: u+ H; q. P1 M) g; D6 i2 _#include <string.h> // memset! X" p% @. A5 C; S6 K8 E5 I
#include <string>. G+ s- L' ]) k0 W' C7 d
#include <iostream>
2 `# h8 _! o( {, ^7 R. C
6 y0 {8 n& D" {7 G |