socket三类型
流式套接字(SOCK_STREAM)使用
TCP协议
数据报套接字(SOCK_DGRAM)
数据报协议UDP,相互独立报文传输
无序的,不保证可靠,无差错。
原始套接字(SOCK_RAW)允许使用
IP协议,用于新网络协议测试
struct sockaddr{ //记录IP地址
u_short sa_family; //指定哪个协议的地址
char sa_data[14]; //14字节的特定协议地址
}
struct sockaddr_in{ //记录网络地址,
通常使用这个
short int sin_family; // 协议族 AF_INET
unsigned short int sin_port; // 端口号
struct in_addr sin_addr; // 协议特定地址
unsigned char sin_zero[8]; //填0
}
typedef struct in_addr{
union{
struct{
unsigned char s_b1,s_b2,s_b3,s_b4
}S_un_b;
struct{
unsigned short s_w1,s_w2
}S_un_w;
unsigned long s_addr;
}S_un;
}IN_ADDR;
将网络地址转换成常用的1.0.0.1形式
int inet_aton(const char*cp,struct in_addr*inp)
char *inet_ntoa(struct in_addr in)
a代表ascii,n代表network
网络字节序(big endian大端)低字节先传输
htons
发送前使用
把unsigned short 类型从主机序转换到网络序
htonl
发送前使用
把unsigned long类型从主机序转换到网络序
ntohs
把unsigned short类型从网络序转换到主机序
ntohl
把unsigned long类型从网络序转换到主机序
struct hostent*gethostbyname(const char*hostname)
struct hostent
{
char *h_name; //主机正式名称
char *h_aliases; //主机别名
int h_addrtype; //主机地址类型 AF_INET
int h_length; //主机地址长度
char **h_addr_list;//主机IP地址列表
}
#define h_addr h_addr_list[0] //主机的第一个IP地址
编程函数
socket 创建一个socket
bind 用于绑定IP地址和端口号到socket
connect 该函数用于与服务器建立连接
listen 设置服务器能处理的最大连接要求
accept 用来等待来自客户端的socket连接请求
send 发送数据
recv 接收数据
TCP网络程序设计
基于TCP-服务器
1.创建一个socket,
用函数socket()
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP
2. 绑定IP地址、端口等信息到socket上,
用函数bind()
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
3.设置允许的最大连接数,
用函数listen()
4.等待来自客户端的连接请求,
用函数accept()
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
exit(1);
}
5.收发数据,用函数
send()和recv(),或者read()和write()
if((nbytes=read(new_fd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
}
6.关闭网络连接
基于TCP-客户端
1.创建一个socket,用
函数socket()
2.设置要连接的服务器的IP地址和端口等属性
3.连接服务器,用函数
connect()
4.收发数据,用函数
send()和recv(),或者read()和write()
5.关闭网络连接
基于UDP-服务器
1.创建一个socket(),用函数socket()
2.绑定IP地址,端口等信息到socket上
3.循环接收数据,用函数recvfrom()
4.关闭网络连接。
基于UDP-客户端
1.创建一个socket(),用函数socket()
2.绑定IP地址、端口等信息到socket上,用函数bind()
3.设置对方的IP地址和端口等属性
4.发送数据,用函数sendto()
5.关闭网络连接
服务器模型
同一时刻只能响应一个客户端的请求
同一时刻可以响应多个客户端的请求
UDP循环服务器
socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}
TCP循环服务器
一次只能处理一个客户端的连接。
socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
process(...);
close(...);
}
TCP并发服务器
每个客户机的请求不由服务器直接处理,而是由服务器创建一个子进程
来处理
socket();
bind();
listen();
while(1)
{
accept();
if(fork(..)==0)
{
process();
close();
exit();
}
close();
}