[size=13.3333px]一 三种类型的套接字:* T2 r' y) }& Z* q- S4 X5 f4 R
1.流式套接字(SOCKET_STREAM)
2 T9 q( l/ d* R8 | 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。
# d% B9 u p& M9 N+ C; }2.数据报式套接字(SOCKET_DGRAM)9 _ q# U1 N1 j. {, z
提供无连接的数据传输服务,不保证可靠性。
9 M" x5 w3 P& u3 K3.原始式套接字(SOCKET_RAW)
3 v6 ]/ z! K2 k7 j 该接口允许对较低层次协议,如IP,ICMP直接访问。
5 }$ K8 j& }: L% p2 V1 n" P2 J2 |+ J9 w1 `$ l
二 基本套接字系统调有有如下一些:
( e5 m, a" O: u+ h8 [0 D9 C 创建套接字: socket()
8 C# w) K5 m0 \& P0 w 绑定本机端口: bind()
& ?* z& S7 L! k- [1 u$ n 建立连接: connect(),accept()
9 ]$ f2 H- Q: ~& q) f 侦听端口: listen()& `2 ~- n( V, z7 n; c# o
数据传输: send(), recv()
. w: V6 c5 Q" j+ @# V% K 输入/输出多路复用: select()8 g8 f1 d m5 O2 [2 p8 P
关闭套接只: closesocket()5 i+ j0 x5 k _, [) H8 I
4 _; v6 M1 K1 z3 j三 数据类型
8 x( h9 q5 A; k+ w# m struct sockaddr- n1 Z# ]7 a) y
{9 ]5 M- M9 {+ `4 j. P
unsigned short sa_family; //地址族, 一般为AF_INET8 I5 d; H% f3 U
char sa_data[14]; //14字节的协议地址
' ~$ k0 E/ @/ E+ U R% I }
" L% A# c- N$ R# Q: |& |, p$ A
$ K8 d2 A9 M( t/ x struct sockaddr_in
% }" r+ h4 U6 o {0 d3 X. ]# d0 Y) q2 p
short int sin_family; //地址族
/ W6 V' ]) w+ o- r# ^ unsigned short int sin_port; //端口号+ n# W& R3 S$ f# A* r k$ u
struct in_addr in_addr; //ip地址) U: S( j% x( M7 ?7 q
unsigned char sin_zero[8]; //填充
% m* U9 t8 H! S }4 [$ z% m5 T( o$ H
, y% q* o2 U9 [
四 常用函数& e. i1 K0 Z+ B7 v! T3 p; U( g7 M
1 socket(), J$ s9 C2 n9 U! k6 _5 P. W+ D' ]
头文件:
6 p. V6 K; } Y6 v( L #include <sys/types.h>
3 a6 m, l# k% [( U #include <sys/socket.h>
5 b5 R1 y8 `5 X: R$ c+ m 函数原型:
9 r/ f3 G d. a. S" c! u int socket(int domain, int type, int protocol)3 Q& `' |) k$ _- n: @& D% y
domain: 协议类型,一般为AF_INET
% P/ o9 ]+ U0 J$ ?5 W* I type: socket类型
: |" i/ p2 ?' n& } protocol:用来指定socket所使用的传输协议编号,通常设为0即可
+ D5 `5 e3 W$ F) y' W* a u( Z, P( P5 ^ c( g
2 bind()6 a" ^: U3 o2 {4 w
头文件:
0 ]5 k, p+ x- w7 ` #include <sys/types.h>
. C; E& t& O2 H$ h) i. h8 A #include <sys/socket.h> m% M/ k4 L- y: ~1 E$ Q& \
函数原型:, r" I+ _# |$ G3 c7 o3 A
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
0 P! S5 S5 U4 H% H7 c. [* a sockfd: socket描述符" V2 Z* Q# _+ z* A" G
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
% l7 z: d$ n8 H3 Q2 O# b% F( f addrlen:常被设为sizeof(struct sockaddr)
% q* X3 M! c2 d' C, {% |4 p. `1 _" P" U. v& X# v
3 connect()
) }& Z- O- N' m 头文件:
\, G9 F9 Z) L8 D+ \% W5 Y #include <sys/types.h>
) t: e5 a4 @, z$ X, G #include <sys/socket.h>$ k) X, O' c1 W# g6 c: s
函数原型:
/ }) Q$ t7 z9 ]6 E$ |7 f+ [2 J' n1 S int connect(int sockfd, struct sockaddr *serv_addr, int addrlen). p" Q1 }$ a2 f
sockfd: 目的服务器的socket描述符
5 [9 Y4 v: ~6 A7 M) z, q" { serv_addr:包含目的机器ip地址和端口号的指针
2 b7 K q3 y% j/ S. n addrlen:sizeof(struct sockaddr): S1 [2 i$ \3 U j4 d3 e8 K
0 g& Z. H0 x. L5 {7 M+ h
4 listen()
% X1 J5 x+ Z9 G9 F( X& P4 a" z% f 头文件:
0 p) y3 Y3 k0 F #include <sys/socket.h>
' H" _8 U6 q8 q; g 函数原型:
0 _2 J- ?$ I% l int listen(int sockfd, int backlog);0 B! z3 I2 F+ _+ J) ~- X
sockfd:socket()系统调用返回的socket描述符3 E9 X9 D7 X( D- Z* F2 R
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。4 e: ^7 ?8 N8 A2 M/ M* M1 q9 M
x; O5 `/ t4 f! o$ | Q 5 accept()
( B- A5 ]: k# F) p 头文件:
* [. |' Z8 H9 A! Z6 c% p5 ], v: Y #include <sys/types.h>( t- Z* D& p2 W2 U6 X/ m2 v8 n
#inlcude <sys/socket.h>- ~- n7 I" \$ N7 s- g2 {; o
函数原型:- ^0 L5 l5 n C" Z+ e
int accept(int sockfd, void *addr, int addrlen)7 r2 [( `% s8 o% c1 t& C
sockfd:是被监听的socket描述符9 q' d7 r+ `6 D& ]
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息8 E( N9 M% N- c' f! M
addrlen:sizeof(struct sockaddr_in)- e% W$ L* M! ~/ o: n) Z
4 ]/ ~" A# a4 x O; @" J9 G
6 send()
8 i' v% s+ E* K5 D4 D/ B) ^5 Z0 O 头文件:' q* u o7 H3 {5 b5 D" T7 `
#include <sys/socket.h>( B* K9 } u: ]0 \
函数原型:
; z7 ]( n. G. A: T# R: K7 C int send(int sockfd, const void *msg, int len, int flags);: O b3 g4 t/ B0 f8 o
sockfd:用来传输数据的socket描述符
7 J4 C! J5 @. H- R2 m msg:要发送数据的指针
7 G- |4 k5 X; S+ F9 V flags: 0
) m8 v& v) Q0 Y1 z& I! @$ w( O & m- w. z, s" {) }( C; _
7 recv(), `2 C2 x1 k) f
头文件:. r$ n1 r( b# W4 i# Y1 A
#include <sys/types.h>
3 j2 r$ [/ r2 d" u #include <sys/socket.h>3 E2 q6 p1 o$ Z. S8 }/ }' w" }
函数原型:
: I4 V6 n( Y, L% W int recv(int sockfd, void *buf, int len, unsigned int flags)
2 |0 }+ [+ [( G' T, d# e sockfd:接收数据的socket描述符
( @# o; v" A3 D; [* C& {8 J buf:存放数据的缓冲区; ?" V. ?2 q8 l+ B! R1 I% j x
len:缓冲的长度" R/ `8 g) {/ H
flags:0 R* N+ K! N7 C7 U; s8 a/ ]& w
1 D! T V2 U3 A0 s 8 sendto()
1 i/ A0 P6 f+ r( w 头文件:
" j. a9 V7 n2 _9 W8 `* M/ A* u #include <sys/types.h>+ M% ^& X! c$ y
#include <sys/socket.h>4 q: d9 Z! l/ a+ n+ r1 f5 [0 O
函数原型:/ V* w2 k* X% V( X
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
/ u3 d/ F. g3 y0 V
# e- ? y" t9 q
! ]& P. D9 p! y9 G" v. Q 9 recvfrom()/ M6 x9 H- y% I5 W
头文件:" M1 [' H- c3 G
#include <sys/types.h>
4 ^( F% M' W' {' U #include <sys/socket.h>
0 o, r% I) P8 }- Y2 }4 d: }( S7 D! M 函数原型:, x& B4 A, z5 |+ k) c$ W
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
! S" _7 `9 w& o
M N0 |- p/ T/ p/ x8 u/ |
" O8 C7 F! D- W4 _7 m; f; Q% g+ M6 G 10 read() write()
( U+ u: [ v5 s' G# \" ^ int read(int fd, char *buf, int len)
; d- H# s* L$ [/ R( G int write(int fd, char *buf, int len), G( R/ T+ O( O- ]4 Y0 ?1 z
9 D6 X3 ^' Y% L- \
11 shutdown()5 ^* t; ~" I; V6 a
close(sockfd)
) m* @5 s. S1 |- C' N3 l int shutdown(int sockfd, int how)) t* ^- i0 ~& B8 e6 m2 E8 n& }
----------------------------------- [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等) " g, o% z7 _2 L1 ]- x2 p- P; D
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等
! {. s- R; y1 m* {; q# C% S<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
5 H- v& k. }: g" T Q<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
% m, _& p$ Y- F2 w# h" ]<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
$ x5 u1 h2 k( \+ {7 ~3 {8 [<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
# r4 X# D! C/ t# M# r! X<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件8 x8 L7 W, n! |6 l$ p; h
1 ~% W9 a; Y, I: X) }
[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等6 w/ }. u5 S# L
#include <sys/types.h> 9 E: i, M8 C/ o# U: N) Y T
0 f* H( z$ M2 X# R7 o#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons \/ p" O' _: g
#include <poll.h> //poll,pollfd
3 s1 F9 Z3 N7 v; m0 K- ]: A8 Q#include <arpa/inet.h> //inet_addr,inet_aton6 [2 H1 n: F7 K7 J
#include <unistd.h> //read,write! }" w m' b# }2 U2 d; {* b& l
#include <netdb.h> //gethostbyname0 U+ j9 S" C/ b- q6 \" `
3 ?3 {& \6 a( T+ u1 \. T" Q#include <error.h> //perror
& Y: E/ S5 R4 {. u' W {#include <stdio.h>8 {: r/ O% L \9 k; @
#include <errno.h> //errno
) d; a' S! J* l6 [6 f3 p
8 [& n. n& z% k/ d& |- G% q#include <string.h> // memset% g1 K- U# X. H `4 n
#include <string>/ e& x1 L0 }3 D% N6 P7 N
#include <iostream>: r& M* k. l# M8 ~5 o
1 W3 }. e4 F# ^$ u
|