标签:
目录
1、socket概述
2、地址及顺序处理
3、函数介绍
4、使用实例
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
一个完整的三次握手也就是: 请求---应答---再次确认。
对应的函数接口:
从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。
struct socketaddr{
unsigned short sa_family;
char sa_data[14]
}
struct socketaddr_in{
short int sa_family;//地址族,即使用什么样的地址,IPV4或者是IPV6
unsigned short int sin_port;
struct in_addr sin_addr;//存放IP地址
unsigned char sin_zero[8]//填充0以保持也struct socketaddr 同样大小
}
网络地址和主机地址转换
#include <netinet/in.h>
uint16_t htons(uint16_t host16bit)//主机地址向网络地址转换
uint32_t htols(uint32_t host32bit)
uint16_t ntohs(uint16_t net16bit)//网络地址向主机地址转换
uint32_t ntohl(uint32_t net32bit)
成功:返回要转换的字节序
出错:-1
将十进制表示的地址转换成二进制
#include <arpa/inet.h>
int inet_pton(int family,//协议类型
const char *strptr,//要转化的值
void *addrptr)//转化后的地址
int inet_ntop(int family
void *addrptr
char *strptr
size_t len)//转化后值的大小
成功:0
出错:-1
gethostbyname()将主机名转换为IP地址
gethostbyaddr()将IP地址转换为主机名
#include <netbd.h>
struct hostnet *gethostbyname(const char *honstname)
成功:hostnet类型指针
出错:-1
int getaddrinfo(const char *hostname
const char *service
const struct addrinfo *hints
struct addrinfo **result)//返回的结果
成功:0
出错:-1
struct hostnet {
char *h_name;//主机名
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;//指向IPV4的地址指针数组
}
#include<sys/socket.h>
int socket(int family,int type,int protocal)
成功:非法套接字描述符
出错:-1;
#include<sys/socket.h>
int bind(int sockefd,struct sockaddr *my_addr,int addrlen);
成功:0;
出错:-1
#include<sys/socket.h>
int listen(int sockfd,int backlog)
#include<sys/socket.h>
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
#include<sys/socket.h>
int connect(int sockfd,struct sockaddr *serv_addr,int addrlen);
成功:0
出错:-1
int send(int sockfd,const void *msg,int len,int flags)
成功:发送的字节数
出错:-1
int recv(int sockfd,void *buff,int len,unsigned int flags)
成功:接受的字节数
出错:-1
int sendto(int sockfd ,const void *msg,int len,unsigned int flags,struct sockaddr *to ,int * tolen)
成功:发送的字节数
出错:-1
int recvfrom(int sockfd ,const void *msg,int len,unsigned int flags,struct sockaddr *from ,int * tolen)
成功:接受的字节数
出错:-1
客户端:
测试:
编译server.c
gcc -o server server.c
启动进程:
./server
显示结果:
======waiting for client‘s request======
并等待客户端连接。
编译 client.c
gcc -o client server.c
客户端去连接server:
./client 127.0.0.1
等待输入消息
发送一条消息,输入:c++
此时服务器端看到:
客户端收到消息:
其实可以不用client,可以使用telnet来测试:
telnet 127.0.0.1 8000
标签:
原文地址:http://www.cnblogs.com/void0/p/4233238.html