|
[size=13.3333px]一 三种类型的套接字:+ V) U( n. h1 {+ U% u, b. g
1.流式套接字(SOCKET_STREAM)
0 c. c4 e4 i9 z6 [ 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。* m( a" C7 u& J1 q* t$ [
2.数据报式套接字(SOCKET_DGRAM)- c3 x' [' \+ V6 t
提供无连接的数据传输服务,不保证可靠性。2 [% ~, m9 [. s, ^( K( N1 T
3.原始式套接字(SOCKET_RAW)
3 W. f8 C) U! O1 x. Q4 Y 该接口允许对较低层次协议,如IP,ICMP直接访问。
: P) V8 L1 e% t0 I( s' w, y5 K' q
二 基本套接字系统调有有如下一些:
4 m$ b7 ^" A z( K- s4 Y6 d9 e- k% k 创建套接字: socket(): t9 Q8 q/ |$ N8 u9 {4 L. t
绑定本机端口: bind() E; A) Q4 |* v! u# f0 F9 `
建立连接: connect(),accept()
( h3 E2 b; }/ d/ k5 V! O$ z' ` 侦听端口: listen(): f6 F3 @" H/ [0 X' D
数据传输: send(), recv()
9 w8 @ q/ r# t% s, E+ A 输入/输出多路复用: select(); L1 p: \2 g! j3 Q; L, ~
关闭套接只: closesocket()' [: P/ A5 a0 w( `6 u* L7 x6 Q W
/ Z: A% }" @% N- d9 Y- |$ z" ]
三 数据类型, ^$ b* z+ e$ o8 c
struct sockaddr
" u2 h( }% c- x9 T8 g$ ` {9 p2 O; H/ W5 S7 z& @; a5 ]: y
unsigned short sa_family; //地址族, 一般为AF_INET6 d1 F1 @. g) J( z1 g- Q) U* J% a e
char sa_data[14]; //14字节的协议地址
0 @; \/ s& x6 J- B }, ]1 H7 C2 n$ s0 `% V) {( g
6 R W% D* ?3 l2 h; l( x. l) r6 e
struct sockaddr_in
' u2 a0 \) t% e4 T) D: [ {% o# I! r. K# q7 _( F R# X9 K
short int sin_family; //地址族, `( f3 U+ s9 }) P. K! N
unsigned short int sin_port; //端口号
7 W+ d: z7 M7 J7 f9 ]$ w struct in_addr in_addr; //ip地址
0 Z; Z3 N+ d* j% T0 ~. O* j1 X( r unsigned char sin_zero[8]; //填充
+ i* g7 i1 b+ }' B% t }0 `6 l: P( I B0 e3 ~* v/ T {" j
" y& X: m3 T7 a$ L
四 常用函数6 J, s6 f3 N$ Z4 E1 n# y" M
1 socket()
8 N- C: l1 F, n. d5 f 头文件: 0 j* i! t% I$ U3 Y1 h6 |
#include <sys/types.h>) \, |# a* o- a( S
#include <sys/socket.h>6 E- Q! o; j1 U
函数原型:
' r4 w" [/ j; K) k' S9 ^1 y* P int socket(int domain, int type, int protocol)
+ m H+ d/ K. q$ A$ k: ? domain: 协议类型,一般为AF_INET) q4 { M8 R" I, h
type: socket类型' w% @/ R7 u5 L8 |7 `7 e
protocol:用来指定socket所使用的传输协议编号,通常设为0即可) n6 x' y3 k% @: E2 _# r. \
( S- S: h/ L4 Y P: t2 K& L( e9 z
2 bind()
% ]6 |6 T- s4 G 头文件:
) f) K$ [ M5 y0 c #include <sys/types.h>
6 e# E/ H/ b+ n) J1 D2 | #include <sys/socket.h>0 }" c# q- E: j3 [
函数原型:' D8 W6 _) |2 M* c" _% D
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
/ j# O0 z2 j. s- o sockfd: socket描述符
3 l5 y" t2 C! ?/ x my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
) Y) R8 ^3 U7 Q+ S addrlen:常被设为sizeof(struct sockaddr)
% Z H! j6 w+ P8 [3 E f) K
0 Y H7 G% v! ?9 k& d, ^% [! v; R 3 connect()
( F; s' d" D# l) b" t# d4 [2 s 头文件:
2 u1 a3 k2 l, m) k #include <sys/types.h>
" U+ C- _1 m6 W7 a- ] #include <sys/socket.h>. x/ I# O6 v% T2 V6 q
函数原型:
3 ?$ d2 L4 ?/ q" ^( W9 Q3 Q2 S int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)# t9 _# S" \" y: l; U
sockfd: 目的服务器的socket描述符, I0 o; J4 c. `1 h3 D) c
serv_addr:包含目的机器ip地址和端口号的指针
" n+ g) L! E% x2 F Q addrlen:sizeof(struct sockaddr)8 y# d! u- d# c- ?/ ?# t& {/ a1 V
1 y) H/ }. I. j6 E
4 listen()
, W/ U& y J$ \4 G2 | 头文件:
' x6 g) J7 m! U3 y- P7 n8 s9 p- S #include <sys/socket.h>6 U+ \0 Z8 n! x/ J3 A# A, |
函数原型:% A' b/ X- p4 o
int listen(int sockfd, int backlog);
, w5 I* q8 M1 Z# q sockfd:socket()系统调用返回的socket描述符
5 l' f/ c% o* G0 m9 Q) p backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
, t6 A$ G: M5 x0 W: c& {$ N$ s9 Z/ V5 N$ \/ g
5 accept()2 c b& A! |- Q) c( q# r; c2 R
头文件: 3 V4 }6 e: m+ g2 j1 e0 Z
#include <sys/types.h>! k% W2 Y0 N7 u- y9 R2 ?# h
#inlcude <sys/socket.h>5 d* q; j5 L: s& C" Q' t, x9 [5 x
函数原型:
% U& V6 q' @/ O/ N) l2 y+ T int accept(int sockfd, void *addr, int addrlen)7 a" _; m# c9 J: Y2 L7 v+ S/ k& K0 P, o& ]
sockfd:是被监听的socket描述符7 Y# I( f, g4 ~1 I* E
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
) @5 z/ _, F( U6 d; F" k addrlen:sizeof(struct sockaddr_in)
( ?, H( g7 x9 _! r1 N1 I& H6 O 5 L3 u* V/ K) {3 D
6 send()
1 B7 [4 E/ H8 w7 b 头文件:
. d: ?5 s( w+ f4 h #include <sys/socket.h>
6 b% s5 T, z! s# P, M' a& k 函数原型:* u+ i% A0 r. Q. i3 w9 D# m
int send(int sockfd, const void *msg, int len, int flags);" ], D4 ^& J' j! I! m
sockfd:用来传输数据的socket描述符
6 @% m% `4 d0 g3 B6 Q msg:要发送数据的指针
' a$ ^( ^! w3 D. w flags: 03 V& G9 `3 }1 C3 P- ^7 n
, C) ? b) M5 }8 R% ^0 l
7 recv()" r7 j* J0 N' g' z% t' E$ _* s
头文件:
/ |7 P: Y# s8 ~# V0 b #include <sys/types.h>
# @! ~3 ]8 }& T, K' g4 N% z #include <sys/socket.h># v8 [& ^1 x7 \2 |2 o. J3 L
函数原型:. B: Q8 ]. M/ D/ p4 M6 ?6 |
int recv(int sockfd, void *buf, int len, unsigned int flags): f% f3 c9 G- M' K8 y. B
sockfd:接收数据的socket描述符
~' s4 D9 ]# [, D6 C$ ? buf:存放数据的缓冲区0 C2 `5 o/ i* p2 F u
len:缓冲的长度
, H& u4 X7 D2 ^" b8 l( T, _: W flags:0
; j- @% K! d( [; [/ u6 j, F3 |3 _7 z* d/ a" g
8 sendto()2 s& y; i2 w# o& N% J8 ?
头文件:2 ] k7 N& U1 |3 Z/ \% d
#include <sys/types.h>- F/ e# M! s/ P6 G
#include <sys/socket.h>2 D+ ]7 S$ H' I7 x+ A$ Q; C; I
函数原型:
" n" y0 z. @5 L, l int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);8 U S: ^- S9 @$ @+ m6 |
4 T1 b! [! F1 S% c8 q* k/ V( ~7 d 8 H$ o: i/ n1 D# S: p; I
9 recvfrom()
9 [0 W6 @3 N% ^6 Z" q% I 头文件:5 U' H7 H; s: O. s# |
#include <sys/types.h>
* V) D$ _4 f/ N; Y+ r- C4 V #include <sys/socket.h>* t8 e; l9 a4 `1 r7 {* e: n
函数原型:" c4 E, J6 r( d/ j: n7 q! |( i& ^9 r
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
/ w* ~% Z3 _3 }$ e6 P d! ]: F7 d3 L a
9 M$ x! ? u( [4 | d
10 read() write()* w; z5 |! U9 i. z8 E6 G
int read(int fd, char *buf, int len)
7 V' u! B7 N% D: [) l d4 y int write(int fd, char *buf, int len)% E, E2 a9 O1 t J9 m
6 y/ p+ A* l4 S, T* Q& r/ @. Y
11 shutdown()9 f/ K) S5 E4 r! G
close(sockfd)5 X! m$ _+ W2 K( `* P& {$ Z" l2 M3 p
int shutdown(int sockfd, int how)
2 w# U5 z' m' N3 V) 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等) 1 ^4 C o, p/ P" B
<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等3 j7 k% j2 a5 H6 G6 ^7 J
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl() d7 K% Z' l/ n! Z2 W* \. n, r2 U
<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等& k) U; n$ R3 R- F" D# {; L0 i! a! A
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等5 V7 s3 U Q# ?; ~+ L) O9 `, H$ \6 o7 b
<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等
; u9 Y0 o$ }: z% O- b: X<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件5 D8 _( @3 y& [, Q0 C0 K/ f
$ Y- Y7 e) f4 E9 K[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等
; C9 D, U M6 I4 k8 k#include <sys/types.h> + v: _! w: e) n6 Z
# o* T. V" i3 P' I6 ]5 w#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons
" ?# Y; m3 C- v$ R! n) |#include <poll.h> //poll,pollfd
) m' H# q7 v4 I: g. V) d( l4 U#include <arpa/inet.h> //inet_addr,inet_aton
7 w2 }7 j; o& ?5 \" q7 ^! {#include <unistd.h> //read,write
; ]; ]8 u4 R9 O5 m#include <netdb.h> //gethostbyname8 D0 n+ r8 R _
+ A# U8 M# a* l& [. p- R1 m
#include <error.h> //perror3 m# e) T4 X, P4 M/ ?
#include <stdio.h>
+ q: q* t2 b" Q. K) w7 c#include <errno.h> //errno
* |: K+ c' c, w; U% e* u1 t
; m, _# d$ K; U+ o& X7 v* p#include <string.h> // memset
0 L; G+ ^7 I3 e& Z/ ?1 e" y- L, C#include <string>0 w2 ~5 H, e* [, C$ N2 z# _) t
#include <iostream>
; O7 T3 L1 n7 H# _2 G* O5 ?- r1 X1 N' _) q r
|