Socket类型
流套接字(SOCK_STREAM)
1. 可靠的、面向连接的通信。
2. 使用 TCP 协议
数据报套接字(SOCK_ DGRA M)
1. 无连接服务
2. 使用 UDP 协议
原始套接字(SOCK_RAW)
允许对底层协议如IP、ICMP直接访问
基于连接的服务
Server程序的作用
程序初始化
持续监听一个固定的端口
收到 Client的连接后建立一个socket连接
与Client进行通信和信息处理:
1. 接收Client通过socket连接发送来的数据,进行相应处理并返回处理结果,如 BBS Server
2. 通过socket连接向Client发送信息,如Time Server
通信结束后中断与Client的连接
Client程序的作用
程序初始化
连接到某个Server上,建立socket连接
与 Server 进行通信和信息处理
1.接收Server通过socket连接发送来的数据,进行相应处理
2.通过socket连接向Server发送请求信息
通信结束后中断与Server的连接
无连接的服务
UDP编程的适用范围
部分满足以下几点要求时,应该用UDP:
1.面向数据报
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高
例子:ICQ、视频点播
具体编程时的区别
socket()的参数不同
UDP Server不需要调用listen和accept
UDP收发数据用sendto/recvfrom函数
TCP:地址信息在connect/accept时确定
UDP:在sendto/recvfrom函数中每次均需指定地址信息
UDP:shutdown函数无效
Byte order
网络字节顺序(NBO,Network Byte Order)
1.使用统一的字节顺序,避免兼容性问题
主机字节顺序(HBO,Host Byte Order)
1.不同的机器HBO不相同,与CPU设计有关
2. Motorola 68k系列,HBO与NBO相同
3. Intel x86系列,HBO与NBO相反
Byte Ordering Routines
主机和网络字节序值转换函数
socket system call
#include
#include
int socket(int domain, int type, int protocol) ;
1.domain参数描述将使用的协议族 。
AF_INET用于表示因特网协议族 。
AF_UNIX用于表示Unix管道功能
2.type参数表明通信的语义。
SOCK_ STREAM说明是字节流。
SOCK_DGRAM则表明是面向消息的服务,像UDP提供的一样
3.protocol参数则指明将要用到的特定协议。一般为0
socket返回值是新创建套接字的句柄(handle),即以后引用该套接字时使用的标识符。在套接字的其他操作中,它也将作为一个参数。出错返回-1。
练习:建立全双工的“管道”
int socketpair(int domain, int type, int protocol, int fd [2 ]);
domain=PF_LOCAL
type=SOCK_STREAM
protocol=0
int bind(int sockfd, struct sockaddr * address, socklen_t addrlen) ;
1.bind操作:如其名字一样,是将新创建的socket与address绑定。这是本地参与者(即服务器)的网络地址。
注意,address在因特网协议中使用时是表示一个数据结构,其中包括服务器的IP地址和TCP端口号。端口号通常是一些众所周知的、专门提供给服务的号吗;例如,Web服务 器通常在端口80上接受连接。
2.成功返回0,失败返回-1。
通用的套接字地址结构
#include
struct sockaddr {
unsigned short sa_family; /* 地址家族 , AF_xxx */
char sa_data [14 ]; /*14 字节协议地址 */
} ;
结构中sa_family为套接字的协议族地址类型,例如对于通常的TCP/IP协议(IPv4),它的值是AF_INET;sa_data中存储着具体的协议地址,不同的协议族有不同的地址格式,sockaddr是一个通用型的结构。
sa_data的存储内容往往是包含地址和端口信息,而仅使用一个变量,所以使用起来不太方便。
使用TCP/IP协议时,sockaddr结构的并列形式
struct sockaddr_in {
short int sin_family; /* 通信类型 */
unsigned short int sin_port ; / * 端口 , 2 bytes */
struct in_addr sin_addr ; / * Internet 地址 , 4 bytes */
unsigned char sin_zero[8]; /* 填充的空白信息,这样就保持整个结构与 sockaddr结构的长度相同 * /
};
其中,in_addr结构定义如下:
struct in_addr {
unsigned longs_addr ; // 网络字节顺序
};
Internet地址转换函数
1.int inet_aton(const char *cp, struct in_addr *inp);
2.char * inet_ntoa(struct in_addr in) ;
inet_aton将点分十进制IP地址字符串转换成32为数字表示的IP地址存入in_addr所指结构中。地址有效返回非0值,无效返回0。
inet_ntoa将一个32位数字表示的IP地址转换成点分十进制IP地址字符串
字节顺序转换
1.htons()-- "Host to Network Short "
2.htonl()-- "Host to Network Long "
3.ntohs()-- "Network to Host Short "
4.ntohl()-- "Network to Host Long "
const INADDR_ANY
An unsigned long int value.
When INADDR_ANY is specified in the bind call the socket will be bound to all local interfaces.