[size=13.3333px]一 三种类型的套接字:
8 g& o( H: i8 y0 w1.流式套接字(SOCKET_STREAM)6 U3 Y; |7 k& t, y
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。7 Z& X+ M2 o3 B: o5 j
2.数据报式套接字(SOCKET_DGRAM); ^) _4 I' U3 U; z
提供无连接的数据传输服务,不保证可靠性。
. y2 u. r* Q$ n# s3.原始式套接字(SOCKET_RAW)
! V* V& k1 f4 ]$ D2 A4 T 该接口允许对较低层次协议,如IP,ICMP直接访问。* ]) R r' N! o: P
* L% @9 `) ^; B& A. x$ O; v& v
二 基本套接字系统调有有如下一些:
" S$ j9 R8 P* \8 ? 创建套接字: socket(); e& m) g5 T; @, {
绑定本机端口: bind()1 v1 P- |# Z3 _: d
建立连接: connect(),accept()7 U0 R/ L# c! p$ \4 [
侦听端口: listen()
* S! y2 _5 @4 y5 c$ r! I. N 数据传输: send(), recv()0 v" ]; {+ ?% S( M' [
输入/输出多路复用: select()
5 G* x1 r- b* n& A/ J 关闭套接只: closesocket()( A& c) h8 }5 ] Q; Y) L& _! q! z
, C+ i/ p! t% P* _8 f; ? F# j三 数据类型
9 }1 m$ G% v7 S- T9 q5 i. q( V' R struct sockaddr4 B; l4 E) @/ D& y3 O" h% _# P
{" ^- Y/ |9 V: s) d
unsigned short sa_family; //地址族, 一般为AF_INET
4 ]3 f _, t- I1 ` char sa_data[14]; //14字节的协议地址
* _# D6 L6 r4 g' L" J; J" W/ S: ] }3 ^" l: R' p. M8 z# _, d/ {3 E8 r
1 m& x4 K/ V! ?# O- i. p
struct sockaddr_in
/ F$ K8 V0 d2 p2 e) K# k% R( ~- Y {6 J# L* e$ Z. x; b# b8 V6 h z
short int sin_family; //地址族
" ^; V6 h1 H4 S' @ unsigned short int sin_port; //端口号
: Y4 n7 a+ W" N0 B5 C$ S5 A* U struct in_addr in_addr; //ip地址- ]: S7 ~6 q. p K0 E+ r
unsigned char sin_zero[8]; //填充
6 G- z1 u4 x( j& f" b }
0 ?* G/ l- x- p3 |% Q
0 E$ ?: E. r/ D* @. m" O! A四 常用函数
8 s& Q2 `9 _0 P$ X6 ^ 1 socket()
- h1 I6 Z9 I& a/ S ^# a 头文件: 6 \4 W, E- G, ~4 [+ N1 n7 ]
#include <sys/types.h>; v+ Z- t( l* I( |% C/ o' G
#include <sys/socket.h>" M% i3 O) M$ d; O/ B( d
函数原型:
9 Q+ t t- f; y+ ` int socket(int domain, int type, int protocol)
; Y! @0 Q' R8 t# ^ domain: 协议类型,一般为AF_INET
1 _5 v l) F) t, t1 ~$ b type: socket类型
* x$ E$ B) f. Y: Z# @- | protocol:用来指定socket所使用的传输协议编号,通常设为0即可" C H& Y1 @- y# w$ s6 {
; M- A' e+ P4 v8 S 2 bind()% P8 J4 a8 p" `
头文件:
{$ Z, g, J0 k& `& ]# n #include <sys/types.h>+ R4 w7 @; A* t' A6 n5 D
#include <sys/socket.h>
% D) K' d0 \/ Z% J* L9 z 函数原型:, O; e5 `7 g9 u
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)" x8 U& V; Z, |5 x# w/ p" P
sockfd: socket描述符* f0 ]* D7 Y0 U$ V0 U" n% k
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
- i& p; z/ p2 w @; v addrlen:常被设为sizeof(struct sockaddr)# q1 e, b" Q1 W' X
! i4 ]% o8 w8 K) p2 T7 A( F- { d 3 connect()
" X" h$ j3 |+ }/ D+ _) O" E 头文件:" R4 z- p; f9 ?; Q
#include <sys/types.h>
: X( K7 u+ k4 \# ~- |# x- j #include <sys/socket.h>
* I: m, K m' Q- d 函数原型:9 S3 t$ ~8 ]2 l3 w
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)3 e% i5 x6 i, e8 K9 y* f( y
sockfd: 目的服务器的socket描述符- P: o' ?6 _" T1 r0 P
serv_addr:包含目的机器ip地址和端口号的指针
/ G: [0 q d6 Y6 S addrlen:sizeof(struct sockaddr)
* [9 ?" [/ I* I$ V% I( [" E7 T8 e: s0 R! m- L, D6 ?6 k
4 listen()6 I$ P% K/ g: O* a' i5 S8 b4 R
头文件:
# [7 H7 R# Q4 \ #include <sys/socket.h>
! [ h! ^' [$ q% F 函数原型:' ?! E$ ~5 N1 @; {8 J/ j
int listen(int sockfd, int backlog);
0 t- w4 U0 O: q sockfd:socket()系统调用返回的socket描述符* B! w0 A e7 D" o7 k
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
7 F! I; c0 {- x& c# \+ E! j* u7 W: P* F8 t! U1 X" L5 O
5 accept()
1 e, N% n) T. t# U+ Z* h 头文件:
9 [9 a" O! Q) K: Z2 L ]3 z" x #include <sys/types.h>
: H3 P7 Z4 e7 B' O- b #inlcude <sys/socket.h>3 s4 E# x) \, {1 V9 J! T& X; h
函数原型:
; V! E2 V$ `' l9 @ int accept(int sockfd, void *addr, int addrlen)
/ ^1 t- l. M# W5 g sockfd:是被监听的socket描述符, x( C$ o& u5 N. P( x- O" K5 l
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息$ K. h7 V& i" J, |1 r$ f. T
addrlen:sizeof(struct sockaddr_in): ?6 C3 m" F5 ?* A2 T
" I( N/ t r- T2 Y2 t 6 send()1 [% K- h+ v$ j; p) |3 a W4 Y
头文件:+ B+ [, V3 z2 S, ]
#include <sys/socket.h>- |: y5 r" F9 j: E7 y6 ]6 F- D
函数原型:
; j" M5 B$ n: |7 L int send(int sockfd, const void *msg, int len, int flags);
! I8 H P8 e6 R% U sockfd:用来传输数据的socket描述符
' g3 E, w' _4 Q' C/ w, O msg:要发送数据的指针 $ x9 i& |0 S6 E% R! x0 O
flags: 0
8 B0 Z8 e7 j- h, L & E3 z, G, ]7 E6 o/ S
7 recv()2 O. G9 {( ]) l# [; C! K' x- `
头文件:
( m# }4 L0 k9 W' ` #include <sys/types.h>% ?3 `" L* h) q" k( o! _- s
#include <sys/socket.h>- X+ `' K% F) A
函数原型:
/ ]) K! t/ _. {' a/ L! o2 B5 w int recv(int sockfd, void *buf, int len, unsigned int flags)
4 O2 O& `$ I/ X0 r/ d4 N4 G sockfd:接收数据的socket描述符
) E2 i% d& u& @& j, N& Q buf:存放数据的缓冲区' X- [( H V* `1 `) [
len:缓冲的长度
- m" D# T: B$ c2 _/ b+ `( d flags:0& f' X# d1 V" a% m, V
; t. T' l& M R( t, t* L 8 sendto(). [; W1 K' g/ ~" Z
头文件:
" ~( H F5 c _) v #include <sys/types.h>" N( }3 P" R( r, Y* ^6 B
#include <sys/socket.h>* @4 q" a$ j$ l+ U
函数原型:
8 a) @6 Q1 s" d1 n4 N" s( ]5 x4 f int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);) s" m& G6 ~1 K. |. D2 W0 \
! M, r( C3 K5 i
% ?/ s4 v; E( V1 ~7 r 9 recvfrom()
9 f# C+ v' N- d; Y% U! A 头文件:9 c c/ c/ K2 K4 y
#include <sys/types.h>
% O; y" Z" O& R! ]$ [6 k6 v* M #include <sys/socket.h>
( K1 l- h, {9 l9 w+ i# q) ` 函数原型:. J2 B" d9 B3 a
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)6 e' a6 E; T9 P
2 X) F( t% z) I: f+ ~/ z
, z* E9 N' U4 g" v* M& p6 ? 10 read() write()
3 K) B3 j: x& p8 N6 x3 l int read(int fd, char *buf, int len)& h7 b" t v2 F7 T4 t
int write(int fd, char *buf, int len)
/ J) L/ P- u6 a3 @% M
# ?- b- U7 C; ~! z" A9 S3 u 11 shutdown()
; W. F) R/ q0 C close(sockfd)
( w0 N6 q6 ]! E int shutdown(int sockfd, int how)
0 S/ U' R2 Y. h9 x& B4 X4 _, e/ _----------------------------------- [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等)
. H$ `; P5 g; c<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等5 ?* Q4 h4 ~, s# S# a& G
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()# R% f4 n# ~' v8 }' K
<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等; D. j- \5 H2 B. Q, ]
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
) r M; N# ]2 f) {, @9 b' l<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
9 K: P4 d1 _ y" m+ D) C<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
) }6 o/ v. m, L% R* q
" v5 B3 w( ?) Y6 i4 i[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等; ?5 e/ s/ x& Z; `! D
#include <sys/types.h>
( B4 S9 S8 G2 n9 j+ X: F; w0 i) H) Q$ g# b3 o. y7 H+ B
#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons: {( n' ~1 U- u6 b7 G2 d
#include <poll.h> //poll,pollfd
+ k/ q* ]5 n3 S( m# L1 i/ m/ k#include <arpa/inet.h> //inet_addr,inet_aton
7 y2 t) ^6 R2 y ], o#include <unistd.h> //read,write
) P3 y# p6 @' D6 ?) P1 Q: J+ H, E#include <netdb.h> //gethostbyname
+ q' g o# |9 [4 n, t+ `& \
# S) {3 T1 \3 u' E) k; ~#include <error.h> //perror
8 g9 Y) k' t4 V* h#include <stdio.h>' Q& L5 y) \2 w
#include <errno.h> //errno7 Z2 C. l& X/ ?; Y! y
- H) d7 |0 G' r1 R+ E
#include <string.h> // memset
4 c3 P3 [, ?) X! J#include <string>
! v6 V' T: }, z#include <iostream>
: D( A( v- M: F# M. a
) g' ?/ ]! N8 |6 R# q |