[size=13.3333px]一 三种类型的套接字:$ [5 [" N* r* Q+ g% l3 L5 V
1.流式套接字(SOCKET_STREAM): \9 y2 E+ B V4 @6 K- e
提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。
6 R' d3 z/ m! W# ^8 L& {2.数据报式套接字(SOCKET_DGRAM)
+ a+ g# x8 g" W, d s6 ~ 提供无连接的数据传输服务,不保证可靠性。
6 O9 n6 D2 z& l2 w9 @7 }3.原始式套接字(SOCKET_RAW)
F- a* y6 F. \- S/ C 该接口允许对较低层次协议,如IP,ICMP直接访问。
* R( l; h$ j) H# ^' b6 W) e
& R# f2 H* q' s二 基本套接字系统调有有如下一些:
' ]- r W. M6 g( |7 D, B% U' }+ Y% G 创建套接字: socket()( M3 l& R! n T6 S8 M
绑定本机端口: bind(), @1 J( t7 u* Y5 V+ J% U' \$ }
建立连接: connect(),accept()
; O+ D# U. G% I2 k/ V 侦听端口: listen()& w# q' I" V# O
数据传输: send(), recv()
5 {" Z9 |9 E9 \5 p' d& E* y5 { 输入/输出多路复用: select()
& h0 P4 s" f9 h) e% x 关闭套接只: closesocket()3 Q4 v% c7 O) `
! q* [: g) V, j, j: G/ z三 数据类型3 s6 ~1 [4 ~* a7 G0 J" @0 H
struct sockaddr
+ U5 h& E6 E! R' `& K |5 E! c {
0 V+ [/ a' M/ J8 i# V, N: _ unsigned short sa_family; //地址族, 一般为AF_INET4 x, u, Q8 c6 X$ l9 T9 {
char sa_data[14]; //14字节的协议地址( l1 c' L5 L' @4 ~) y
}5 L( G7 y4 `8 r5 j, }# K
% L6 y& H6 z+ \# @6 L5 f- w struct sockaddr_in9 w% G' `7 I1 Y) {
{. X! r8 r% l. X. {9 H. ]
short int sin_family; //地址族+ X' b& y. ?. p0 \/ S! A2 Y; ~9 f
unsigned short int sin_port; //端口号/ L N! n, A$ h0 f* g6 }" p
struct in_addr in_addr; //ip地址
) w* F* ?- U! P, o& w, B unsigned char sin_zero[8]; //填充
9 n/ Q. C7 w# P3 Q2 C }7 l* O2 i# i' \2 f8 o
5 p& E0 L5 J( o) J6 n& V
四 常用函数
^4 C/ Z+ D6 t" s 1 socket()
+ }; x, M2 \& \& g; P+ O, C5 l 头文件:
) f9 R0 F) n( h- a #include <sys/types.h>7 `1 n/ O$ Q7 u- F
#include <sys/socket.h>, {* ~, J! G* X
函数原型:/ ^9 Y9 l" y8 |2 D- Z$ X2 ^4 F
int socket(int domain, int type, int protocol)% p/ A' k+ I1 E
domain: 协议类型,一般为AF_INET) ^- ~0 g7 q: K
type: socket类型! p8 l* a2 T m0 E
protocol:用来指定socket所使用的传输协议编号,通常设为0即可
( ^, j4 T3 N% Q
4 E& m V0 C6 {4 q: B 2 bind()- f& u: ?5 ~& O1 ]* {) w3 ?
头文件:$ b1 w. Y' }) |8 i3 m9 p( s1 D3 k
#include <sys/types.h>
# e' {% J# x( r; p #include <sys/socket.h>0 M# G0 N; L/ ] u. ~
函数原型:
$ l7 p+ P( S" s( w4 C int bind(int sockfd, struct sockaddr *my_addr, int addrlen)" _7 i0 D2 U' p; V( }
sockfd: socket描述符6 L, O& v* }5 `! E( T+ r# S
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
8 L* c) E5 h2 a! d addrlen:常被设为sizeof(struct sockaddr)
# X. r3 h" }5 ~4 k! T# }9 C6 P/ d( s! ~5 P4 ~* v" v
3 connect()2 R) p! s1 K! O3 p+ t# `
头文件:
" Z% c: E. x! v8 ?: i" v #include <sys/types.h>
: J( Y' K& M3 c7 ~6 F #include <sys/socket.h>
+ w' k: W6 X" V 函数原型:8 k$ I" \- d, f5 `& l" D. b
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); j# ]- D# [3 ?
sockfd: 目的服务器的socket描述符2 {: M: O* d- L
serv_addr:包含目的机器ip地址和端口号的指针$ |% X0 f; o6 P( t5 B2 x
addrlen:sizeof(struct sockaddr)1 c! s& w3 M5 @6 {8 Z
9 e1 t( R3 Z3 |5 `6 ^ 4 listen()
6 Y3 G( @2 d: X( f# q 头文件:
- n9 e* o9 L% R5 j7 Y #include <sys/socket.h>3 f; h9 t. g! s0 `/ E) c
函数原型:
0 L* O' a3 ~3 c" X* R g7 V$ n k int listen(int sockfd, int backlog);
r1 D4 W' l, g6 N/ ~& G/ t! i sockfd:socket()系统调用返回的socket描述符 V: h) `1 G9 J) t! ]% V
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。- G8 r/ Y/ ~1 k' E# x' A# p7 `* A
1 o8 E/ Y6 s" [; S& W: Q) R& O, K
5 accept()- ^) L- \, i- X, g( v' X" O+ x5 j
头文件: . Z' e5 N' w! O
#include <sys/types.h>' i% ^ z4 d- q( z8 \
#inlcude <sys/socket.h>
0 p& W& K0 U% \( H' z7 ?* O 函数原型:
) E9 G0 {+ E3 s6 V int accept(int sockfd, void *addr, int addrlen)6 r7 D P6 O. C8 u
sockfd:是被监听的socket描述符
/ N( K% [! j u addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
4 U8 j1 k2 t/ y0 z( S d, T; i addrlen:sizeof(struct sockaddr_in)1 b# t. u* u8 F0 S
0 q/ I4 u: J/ K) A
6 send()
: b: g2 k! w6 z7 [ 头文件:
( c3 y/ m& g, H; R #include <sys/socket.h>8 ?1 f! R8 q# a9 {4 J1 V
函数原型:
1 e. W3 z J3 V: a int send(int sockfd, const void *msg, int len, int flags);' K0 n: Y$ @% E7 g. q
sockfd:用来传输数据的socket描述符; p! k" ^- E1 v% ?; ~2 m7 V* c
msg:要发送数据的指针 ! N9 ?/ W) R9 d4 A( w( y4 P
flags: 0
/ y% m1 M7 z* D" o+ C7 n 9 O2 F' b0 k$ |3 h T0 Z" U
7 recv()- M1 f; @ h0 k* E- Y8 O
头文件:) Y) f9 c) z+ M
#include <sys/types.h>
0 \4 t' ?1 y1 \, _3 |, A5 k5 S5 ~8 T, ] #include <sys/socket.h>
$ z( p6 p4 Y/ R a" ^ 函数原型:
" ^; Q4 e7 a+ E v$ C% B( Y2 y( V4 J- T int recv(int sockfd, void *buf, int len, unsigned int flags), r, h0 u3 ^ F X
sockfd:接收数据的socket描述符2 ^* D0 U6 R2 p! s9 I
buf:存放数据的缓冲区4 Y& w' m6 o6 T1 Z% o
len:缓冲的长度6 ]/ O$ N9 A9 k" p
flags:0
# v* h4 S; `! j/ R8 m `- }+ m' `! F+ X; }1 P
8 sendto()# O% W( R, d+ J3 X) ?: f( t+ s
头文件:
! w7 |7 E4 v8 ~& { U9 F4 Y% v #include <sys/types.h>
( ?9 E7 E+ q* Y5 d0 d* ` #include <sys/socket.h>
& H, n* m, {7 U5 R6 S- `$ \ 函数原型:; V# `" n: }9 P+ v- H
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);* s5 z1 q; _, K, V9 Z# }+ v
3 `, L1 W% G! [. \# k
9 w) `, d! @" N& G d3 ^/ F W 9 recvfrom()* W- ^. n' x3 G) U
头文件:
( J& R+ ~& Q+ V #include <sys/types.h>
. ?- M% U6 A! B" | #include <sys/socket.h>
- o. `0 t7 Q0 ^& Y- }! E0 f8 ~/ { 函数原型:) D# @5 ?# w" b
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)+ V% [6 j! x" @4 m- u& T
0 {+ I. ~2 }3 u / v' @1 F8 a3 X E" ?2 j
10 read() write()
; Q1 ~9 C2 J4 _1 ` int read(int fd, char *buf, int len)6 y. X5 u1 c- z
int write(int fd, char *buf, int len)
# N+ ~1 ~; _: l7 Y! ?3 F) f
, n9 _ }+ m8 G8 ?; v) t 11 shutdown()3 e* }( X4 f' @- s* z W
close(sockfd)* ?' w5 \" O: ^5 J$ }( N
int shutdown(int sockfd, int how)7 e2 |" Q# q1 B4 r
----------------------------------- [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等)
2 `2 A g l) I$ \# I% s<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等8 ^6 m4 N2 @, [* U
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()7 Z8 ]8 Q; } J& W/ X5 I
<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等
0 G) V9 z, Q0 n- w<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等$ i! k. V2 n. J ^9 r
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等, q- D$ R# E: t
<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件
9 s% ?( k1 E" w( u- u$ A* x# @ l* g3 K, ?/ C @
[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等* N4 X$ `: s0 y N4 b7 R
#include <sys/types.h> / P; N7 g9 U6 ^; m! T4 V
3 t- p# w' o7 Y; D [#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons0 X: g0 u4 C& j; ?. p# ?
#include <poll.h> //poll,pollfd
" D" Z/ C1 }0 T/ a l% I. X& ~#include <arpa/inet.h> //inet_addr,inet_aton' I M! c; [ i
#include <unistd.h> //read,write
7 D4 _8 n1 t! \+ E+ \4 V# g#include <netdb.h> //gethostbyname3 o: m( i$ L( i: ?5 C
+ z3 X5 q5 a/ S$ N/ a#include <error.h> //perror
* W% S8 r2 n. u$ X* V; G1 U0 s5 E#include <stdio.h>
0 {8 a# x4 R: L( D$ `' n#include <errno.h> //errno4 O3 Z- L3 Z' j+ k8 d* g
6 a# g9 B d) C7 Q: z5 V#include <string.h> // memset
; q% t! [0 Z3 {5 p+ M& x8 b#include <string>& W; M; B: R3 r
#include <iostream>
/ B, g2 ^$ _& @; q8 m
" R3 l; S5 M6 f, }$ N6 ` |