Socket API介绍
- 在UNIX中socket句柄和其它I/O句柄(文件,管道等)可以互换使用
- 在windows中对于大多数操作socket句柄和 I/O句柄不能互换使用
- 每一个socket句柄绑定至一个本地地址和一个远程地址
Socket API系统函数分为五类:
1.本地环境管理,如 socket()bind()close()等
2.连接的建立和终止,如connect() listen() accept()等
3.数据传输机制,如send()recv()read()write()等
4.选项管理,setsockopt getsockept等
5.网络地址,gethostbyname()等
#include<sys/types.h>
#include<sys/socket.h>
const int PORT_NUM = 1000;
int echo_server()
{
struct sockaddr_in addr;
int addr_len; //错误,addr_len需要设置为sizeof(addr),不然accept()调用失败
char buf[BUFSIZ];
int n_handle;
int s_handle = socket(PF_NUIX, SOCK_DGRAM, 0 );
//windows下socket句柄类型为socket,导致不可移植
if(s_handle == -1) return -1;
//addr结构未初始化为0,地址结构addr根据地址簇的不同结构不同,不初始为0则包含不确定字段
addr.sin_family = AF_INET;//AF_INET为internet地址簇,s_handle为UNIX协议簇,应设置为PF_INET
addr.sin_port = PORT_NUM;//值没有使用网络字节序,使用的是主机字节序,将无法连接到预定的端口号上
addr.sin_addr.addr = INADDR_ANY;
if(bind(s_hanlde, (struct sockaddr * )&addr, sizeof addr) == -1)
return -1;
//未调用listen()函数
if(n_handle = accept(s_handle, (struct sockaddr*)&addr,&addr_len)! = -1)
//s_handlle被创建为SOCK_DGRAM类型,对accept为非法类型,应创建为SOCK_STREAM类型,且此处涉及运算符优先级顺序,在UNIX上则会将数据写到stdout或stdin上,应将n_handle的赋值放在单独一行。
{
int n;
while(n = read(s_handle, buf, sizeof buf) > 0)
//read()调用的是s_handle,是一个被动监听socket,应该调用n_handle。
write(n_handle, buf ,n);
//应检查write()的返回值。防止数据丢失
close(n_handle);
}
return 0;
}