|
[size=13.3333px]一 三种类型的套接字:0 {' [+ o- U" N0 R; i& `. l+ R8 ~# x
1.流式套接字(SOCKET_STREAM)
4 M9 e" u1 j% a+ [7 ~/ D 提供面向连接的可靠的数据传输服务。数据被看作是字节流,无长度限制。例如FTP协议就采用这种。7 X( v2 [) Q8 H! q6 U: O) B
2.数据报式套接字(SOCKET_DGRAM)
! M3 y' G& P8 w. M1 a 提供无连接的数据传输服务,不保证可靠性。: Y" W" m/ O8 l x
3.原始式套接字(SOCKET_RAW)
3 @( v7 a' y$ j9 p: } 该接口允许对较低层次协议,如IP,ICMP直接访问。
3 |# h* X' w, O; Q& o1 N
; j& l/ v# y" ?) A4 ~二 基本套接字系统调有有如下一些:. d5 D8 w0 z8 s0 [6 B: A
创建套接字: socket()
5 F* v! z) u) D8 { 绑定本机端口: bind()
( C- [ l4 B0 V 建立连接: connect(),accept()0 W. w: g+ M( m( j8 T4 S) z& _- k7 ?
侦听端口: listen()
" ^1 Q* I) V* v! z6 i 数据传输: send(), recv()
* [8 e: `& h; d5 j 输入/输出多路复用: select()
# M* z8 d' E& O% U# B* S- a) k 关闭套接只: closesocket(): H! ^. P* H6 ?$ [) R- z
! y& z$ W2 `# `0 i& `+ g$ n三 数据类型1 l& }, Y+ \4 G' ~
struct sockaddr. f0 a% ] a8 `, \( O. I
{
7 o' u2 i0 L& M% `- z6 `; \" Y2 G; v7 k unsigned short sa_family; //地址族, 一般为AF_INET
3 F6 C) v& f. f# _- l$ e) K char sa_data[14]; //14字节的协议地址7 U- L9 D3 s8 Z
}
* u. o/ ]4 Q: t- S$ V" x2 ]
" f' B. |! C* S" R2 d8 k" {4 f struct sockaddr_in( c' W! b x3 I* L( o3 u1 p) V% j$ \
{0 M( D' q# C. J/ J4 P
short int sin_family; //地址族+ V1 c6 n+ Y. Z* \9 D$ G
unsigned short int sin_port; //端口号
5 y- N5 W2 \, c! d- t struct in_addr in_addr; //ip地址3 g- e7 V+ \8 `! _1 v
unsigned char sin_zero[8]; //填充
9 e5 w/ _. U/ W9 W }
/ ^$ C$ {# E! H9 C O+ B$ ~& P$ D0 y# I/ P5 L% X* h3 v
四 常用函数# s2 B7 n2 r/ u" z4 j
1 socket()" G0 l) J0 H( ] C5 H+ I$ ^# W
头文件: % X! I& i$ m3 `- Y: K+ L6 ]% Z
#include <sys/types.h>+ m- G- p( x% s
#include <sys/socket.h>* v6 Y; m4 U( b8 @# m0 A" v
函数原型:
! {1 {/ C3 i; }" H' i2 a int socket(int domain, int type, int protocol)
/ ^$ ~7 Q) e2 G+ u0 j- k domain: 协议类型,一般为AF_INET
5 @0 U) k3 Y( I/ J$ S; c type: socket类型
3 `5 [6 r y6 Q! G protocol:用来指定socket所使用的传输协议编号,通常设为0即可: T* L" K- [- W) O& r$ [& ?
: c3 I# Y0 W5 o% W/ V" Y
2 bind()6 z+ a! P# a! f) m
头文件:
6 w5 C* ~8 O s h, a/ u. c #include <sys/types.h>
# K; W9 J- b4 I2 g! Q- B0 f" W #include <sys/socket.h>
' }* }& r; b/ W3 m 函数原型:) [3 ^1 ?( k, l* q7 k
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)7 C; R/ g/ Y$ @5 |
sockfd: socket描述符3 H; D1 X7 P. o6 q* A1 F2 N0 j
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
' n* g$ _- E; d: E. k addrlen:常被设为sizeof(struct sockaddr)$ T" ]" R/ F- |4 h
* n1 I# d2 [8 k# [8 Y 3 connect()' r/ v2 v4 c- \
头文件:* ^; _" t' N; x+ R
#include <sys/types.h>
5 U" V' m, L* M* C1 N #include <sys/socket.h>1 B# F5 M! L* l! ^, z
函数原型:
1 V3 r, Y0 K3 }4 b9 I+ I" o" h int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); y$ E& p/ G1 K3 K& L; h
sockfd: 目的服务器的socket描述符; x0 I& j6 p* L
serv_addr:包含目的机器ip地址和端口号的指针
) o. `# y2 f2 _4 y2 A" y addrlen:sizeof(struct sockaddr)
! C1 M; Q: h9 f; t" g6 q5 h W9 ^
# d. V$ p; Q0 [7 f1 f0 n& Y" Q 4 listen()
( T7 x1 ]& H5 F, N 头文件:
- d5 b# H7 u5 x+ z9 A( Y) U #include <sys/socket.h>
# H2 C8 a, {' m1 K! | O" m 函数原型:
7 x, w( Y& L) m) D' Q$ H int listen(int sockfd, int backlog);
6 S7 M. x4 D l" f% A4 |7 j9 {8 } sockfd:socket()系统调用返回的socket描述符1 P5 @: ]3 T+ ^! i& x
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
. g* E' R7 d! [+ ~5 @
+ a+ D( k3 ` j, a2 v 5 accept()
* I' p( w2 e# g: I1 C 头文件: 2 F0 G3 d1 X+ S. |, L
#include <sys/types.h>2 p, n7 T( k8 |2 l% I+ q
#inlcude <sys/socket.h>
! A1 l( c! \, w) U3 b 函数原型:
+ R6 n) O4 @7 b! q7 e- H int accept(int sockfd, void *addr, int addrlen)! H0 F' ]. m) l1 m6 N
sockfd:是被监听的socket描述符
6 b( y/ }5 K6 |( i1 Y addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
. ~6 J. Y7 ]* B; q addrlen:sizeof(struct sockaddr_in)
! x- h, V V4 z$ B. q- ?2 b
4 Z) `" l- ?+ H. @ P" S$ ] 6 send()
, r2 H! i# I% U+ B: |, Y N 头文件:0 O0 n$ G0 U) `7 ~9 b! U
#include <sys/socket.h>
1 `" E @$ s! O' V: R( f" O# { 函数原型:
8 X1 h9 i% O3 } int send(int sockfd, const void *msg, int len, int flags);
5 O- J# Z' x! y z F9 f, m, i8 S/ S sockfd:用来传输数据的socket描述符$ B' D. I @! [- n& I
msg:要发送数据的指针
# u5 j0 [' h4 L( z8 R, p flags: 0+ D+ ]# f( s1 X1 x w$ V
8 Y! [! K7 @7 d1 a: }# ^/ o 7 recv()( x8 x4 v6 w7 l; R9 P5 D9 }3 D
头文件:* {+ }0 @ O R! |; ?
#include <sys/types.h>
5 O2 O- }. p3 y* T+ d( w6 N% _ #include <sys/socket.h>- @8 I9 J/ a% H/ b" E8 |$ ^2 T$ {
函数原型:
5 f4 J/ p: v8 M _3 [ i- q int recv(int sockfd, void *buf, int len, unsigned int flags)
; p9 B9 E4 u1 m* A( h. j sockfd:接收数据的socket描述符: n3 I& V0 q* q3 q
buf:存放数据的缓冲区
+ k5 \7 r+ b/ j3 k len:缓冲的长度6 s9 ^( ]9 g6 a1 s. G# V2 e% v
flags:0
" I r" C! f% W' h6 P/ }0 O" w! n. M
8 sendto()
' K8 `$ {4 ~4 \$ i* A- H 头文件:
. K8 J k0 j/ s# _+ Y* T #include <sys/types.h>8 i* p- ^* b, M/ R; ]$ H1 I8 `% C0 r, H
#include <sys/socket.h>
W! S% V0 O/ d( k% H) F 函数原型:
% g0 w! `- `) _, E& I, f3 _ int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);6 ]! `9 P9 S" N1 f, M
. {6 ]" q+ M& l5 U4 s# `
! e4 Z' {" j7 ?5 f8 C2 ~ 9 recvfrom()
: a, B7 ~7 l+ C: y& |" K1 @$ B: S 头文件:
: y8 ?9 h) h- o* K& u- q% \ #include <sys/types.h>
, ^) V, T! c* I# T% n8 j #include <sys/socket.h>0 T( _% m/ T3 U8 X9 K; _
函数原型:
) o2 n# l6 o- M$ N int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
. D6 m+ d0 Y B; o. g) W7 @& Z8 R* h/ R* m o/ o7 X6 J/ M9 `
! ^" H) F: o$ N 10 read() write()
5 N- L, ^5 j6 E2 A( S" H5 O" F int read(int fd, char *buf, int len)3 ?: R! { @% [5 |5 E. v
int write(int fd, char *buf, int len)' k0 `/ s' n* o! G
5 a6 C1 Q& a) B0 V" b
11 shutdown()1 ~7 y- k+ d) P/ x4 Q
close(sockfd)
8 e/ b4 m6 j) o" b& ]( c6 l int shutdown(int sockfd, int how)
2 r) B$ _0 L% i----------------------------------- [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等)
# ^, C4 r/ C3 ^+ w& E- m# f<sys/socket.h> //与套接字相关的函数声明和结构体定义,如socket()、bind()、connect()及struct sockaddr的定义等6 q% \2 E: W8 p( p r
<sys/ioctl.h> //I/O控制操作相关的函数声明,如ioctl()
$ H0 \4 I! p5 k<stdlib.h> //某些结构体定义和宏定义,如EXIT_FAILURE、EXIT_SUCCESS等9 ?' W: [, ^/ K0 R/ {! b
<netdb.h> //某些结构体定义、宏定义和函数声明,如struct hostent、struct servent、gethostbyname()、gethostbyaddr()、herror()等
, k. b) S8 ]( `' \$ N' l' a% |<arpa/inet.h> //某些函数声明,如inet_ntop()、inet_ntoa()等; J/ l( L! {1 u' w6 ~* E4 w3 H2 o
<netinet/in.h> //某些结构体声明、宏定义,如struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 [size=13.3333px]------------------------------ [size=13.3333px]linux下socket编写常用头文件! @: m0 s$ m+ q8 E- ?: r
- ]/ M$ i1 h& k( ]. O; s! H) q* s[size=13.3333px]#include <sys/socket.h> //connect,send,recv,setsockopt等7 D4 V1 ]3 M# N- E: R
#include <sys/types.h>
" c2 ^1 w' X* T, D7 e. E
+ k4 \, J1 Q7 V* B2 E; H: |" y7 g#include <netinet/in.h> // sockaddr_in, "man 7 ip" ,htons8 g8 o$ h$ P4 J! K+ y: _& [; C
#include <poll.h> //poll,pollfd* b8 s) L+ f. v# P* O5 I0 U' X# f
#include <arpa/inet.h> //inet_addr,inet_aton) A6 I+ M X1 d4 |, R
#include <unistd.h> //read,write% l. X; A. z+ { c8 z
#include <netdb.h> //gethostbyname
! S. n& c3 {/ F$ j7 z) b: w* q) e4 r2 t3 f5 N m4 M
#include <error.h> //perror& j* H+ _2 J$ C* W# L
#include <stdio.h>3 w4 Y4 D9 `' S/ ]# h& J
#include <errno.h> //errno+ \. F5 Q# E. t% G
6 O( U5 H7 Q' H. l9 I( R7 }#include <string.h> // memset+ ?, \7 R7 d9 e3 q& q9 R% B
#include <string>
6 I' ]8 e* Q5 _' O#include <iostream>
2 ?7 a, H/ N. S3 [+ l* w- C, Q5 d3 e; A) n$ U8 _& m0 C
|