读用TCP/IP进行网际互连——客户-服务器编程与应用(
Linux/POSIX套接字版)》
第4章 协议的程序接口
第5章 套接字API
第6章 客户软件设计中的算法和问题
这里只是一些简单的概念介绍,不会涉及具体实现。
Linux中六个基本的系统函数用来对设备或文件进行IO操作。
open() \\为IO操作准备文件,返回值是文件描述符,参数有三,分别为要打开的文件或设备名字、一组位标识(bit flag)、访问模式。
close() \\终止使用以前已打开的文件,参数有一,文件描述符,表示关闭文件描述符所指向的文件。
read() \\参数有三,文件描述符、要写入数据的地址、数据长度;
write()
lseek() \\转到文件中某个指定的位置,仅用于文件或类似磁盘的设备
ioctl() \\控制IO
Linux中所有东西都是文件。
网络通信也被看作IO操作和文件操作。
套接字描述符和文件描述符都放在同一个文件描述符表中。系统为每个进程维护一个单独的文件描述符表,文件描述符表是一个指针数组,描述符是其下标,而数组内容指向文件所在的位置,或者说文件的内部数据结构。
网络通信中有五要素,双方通信地址(主机名、IP、MAC)、协议、双方端口。
为允许协议族自由地选择其地址表示方式,套接字抽象为每种类型的地址定义了一个地址族。
TCP/IP各协议都使用一种单一的地址表示方式,其地址族用符号常量AF_INET表示。
地址结构
struct sockaddr { /* struct to hold an address */
u_char sa_len; /* total length */
u_short sa_family; /* type of address */
char sa_data[14]; /* value of address */
}
并不是所有的地址族都定义了适合这种sockaddr结构的端点。
struct sockaddr_in { /* struct to hold an address */
u_char sin_len; /* total length */
u_short sin_family; /* type of address */
u_short sin_port; /* protocol port number */
struct in_addr sin_addr; /* IP address (declared to be u_long on some systems) */
char sin_zero[8]; /* unused (set to zero) */
}
只使用TCP/IP协议的应用程序可以只使用sockaddr_in结构。
socket() //创建一个新的套接字,返回套接字描述符,参数指明协议族(TCP/IP使用PF_INET)、协议或所需要的服务类型;
connect() //参数指明目的地和端口号;
close() //参数为套接字描述符,表示关闭该套接字,若多个进程共享某个套接字,close就把套接字的引用数减1;
bind() //将某个套接字绑定到某个端口上;
listen() //监听,指明该套接字所使用的队列长度,处理传入连接,然后准备接受下一连接;
accept() //从套接字上接受连接,为每个新的连接请求创建一个新的套接字,指向该连接,原来的套接字继续接受其他连接请求。
send()和write()一样;
recv()和read()一样;
shutdown() //在一个或两个方向上终止TCP连接
getpeername() //在连接到达后,从套接字中获得远程机器的地址
getsockopt() //获得套接字的当前选项
setsockopt() //改变套接字的当前选项
网络字节顺序和本地主机顺序转换函数
htons()、ntohs()、htonl()、ntohl();
n : network ; h : host ; s : short ; l : long ;
地址转换函数
二进制地址=inet_addr(点分十进制地址);
hostent=gethostbyname(主机名); //通过域名查找IP
struct hostent {
char *h_name; /* 正式的主机名 */
char **h_aliases; /* 别名 */
int h_addrtype; /* 地址类型 */
int h_length; /* 地址长度 */
char **h_addr_list[0]; /* 地址列表 */
}
#define h_addr h_addr_list[0]
gethostbyname()如果没有找到IP则返回0
用下面的例子来说明以下使用:
struct hostent *hptr;
char *hostname="www.csdn.net";
if ( hptr = gethostbyname( hostname )) {
/* IP 就是 hptr->h_addr */
}
由服务查找端口
servent=getservbyname(服务,协议);
struct servent {
char *s_name; /* 正式服务名 */
char **s_aliases; /* 别名 */
char s_port; /* 端口 */
char *s_proto; /* 协议 */
}
下面示例查找SMTP的正式协议端口号:
struct servent *sptr;
if (sptr = getservbyname("smtp","tcp")){
/* 端口号为sptr->s_port */
}
getserbyname()按网络字节顺序返回服务的协议端口,是sockadd_in结构所需要的形式,打印输出需要转换为本地字节顺序。
由协议名查找协议号
protoent=getprotobyname(协议名);
struct protoent {
char *p_name; /* 正式协议名 */
char **p_aliases; /* 别名 */
int p_proto; /* 正式协议号 */
}
下面示例查找UDP的正式协议号
struct protoent *pptr;
if (pptr = getprotobyname("udp") ) {
/* 正式协议号=pptr->p_proto */
}
符号常量
PF_INET //表示TCP/IP协议族
AF_INET //表示TCP/IP协议族的地址族(地址表述方式)
SOCK_DGRAM //表示数据报服务
SOCK_STREAM //表示流服务
头文件
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
之前章节 {
第1章 引言和概述
TELNET的在linux和WIN7中的使用以及在WIN7中的启用方法
http://blog.csdn.NET/qq_27607539/article/details/73715679
第2、3章
1进程与线程以及Linux中fork()的运用
http://blog.csdn.net/qq_27607539/article/details/73729875
};