文章目录
TCP网络编程
server(服务器代码的编写)
-
1.初始化
-
2.进入一个主循环(死循环)
a.读取客户端发来的"请求"(Request)
b.根据请求内容,计算生成"响应"(Respnose)内容最核心
c.把响应数据返回给客户端
socket():创建套接字
调用格式
- 1.使用socket()函数创建一个文件描述符
int socket(AF_INET,SOCK_DGRAM,0);
//参数一:表示改文件描述符使用的是IPV4
//参数二:表示该文件描述符使用的是UDP协议
//参数三:一般不使用
-
参数domain 用来说明网路程序所在的主机采用的是那种通信协议簇,这些协议族再头文件<sys/socket.h>中定义
-
AF_INET //表示IPv4网络协议
-
AF_INET6 //IPv6网络协议
-
参数type 用来指明创建的套接字类型,
-
SOCK_STREAM:流式套接字,面向连接可靠的通信类型
-
SOCK_DGRAM:数据报套接字,非面向连接和不可靠的通信类型
-
SOCK_RAW:原始套接字,用来直接访问IP协议
-
参数protocol 指定套接字使用的协议,一般采用默认值0,表示让系统根据地址格式和套接字类型,自动选择一个合适的协议
-
返回值:
-
调用成功就创建了一个新的套接字并返回它的描述符,在之后对该套接字的操作中都要借助这个文件描述符,
-
否则返回-1(<0) 表示套接字出错.应用程序可调用WSAGetLastError() 获取相应的错误代码
bind ():将套接字绑定到指定的网络地址
使用这个函数前需要将服务器的ip和端口号赋值到结构体sockaddr_in中
使用bind()函数前的准备工作
- sockaddr 结构:针对各种通信域的套接字,存储它们的地址信息
struct sockaddr{
u_short sa_family; /*16位协议家族*/
char sa_data[14] /*14字节协议地址*/
};
- sockaddr_in结构:专门针对Internet通信域,存储套接字相关的网络地址信息(IP地址、传输层端口号等信息)
struct sockadd_in{
short int sin_family; //地址家族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //IP地址
unsigned char sin_zero[8]; //全为0
};
- in_addr 结构:专门用来存储IP地址
struct in_addr{
unsigned long s_addr;
};
#include<netinet/in.h>
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
-
参数sockfd:是未经绑定的套接字文件描述符,是由socket()函数返回的,要将它绑定到指定的网络地址上
-
参数addr : 是一个指向sockaddr结构变量的指针,所指结构体中保存着特定的网络地址,就是要把套接字sockfd绑定到这个地址上.
-
参数 addrlen :是结构sockaddr结构的长度,等于sizeof(struct sockadd
-
返回值
返回0:表示已经正确的实现了绑定
如果返回SOCKET_ERROR表示有错。应用程序可调WSAGetLastError()获取相应的错误代码
- 最后在函数调用的时候,将这个结构强制转换成sockaddr类型
本机字节序和网络字节序
-
本机字节序在不同的计算机中,存放多字节值的顺序是不一样的,有的是从低到高,有的是从高到低.计算机中的多字节数据的存储顺序称为本机字节顺序.
-
网络字节序:在网络协议中,对多字节数据的存储,有它自己的规定。多字节数据在网络协议报头中的存储顺序,称为网络字节序.在套接字中必须使用网络字节序
所以把IP地址和端口号装入套接字时,我们需要将本机字节序抓换成网络字节序,在本机输出时,我们需要将它们从网络字节序转换成本机字节序
-
套接字编程接口专门为解决这个问题设置了4个函数
-
1.htons():短整数本机顺序转换为网络顺序,用于端口号
-
2.htonl():长整数本机顺序转换成网络顺序,用于IP地址
-
3.ntohs():短整数网络顺序转换为本机顺序,用于端口号
-
4.ntohl():长整数网络顺序转换为本机顺序,用于IP地址
这4个函数将被转换的数值作为函数的参数,函数返回值作为转换后的结果
- 点分十进制的IP地址的转换
在Internet中,IP地址常常是用点分十进制的表示方法,但在套接字中,IP地址是无符号的长整型数,套接字编程接口设置了两个函数,专门用来两种形式IP地址的转换
- 1.inet_addr函数
unsigned long inet_addr(const char* cp);
/*
入口参cp:点分十进制形式的IP地址
返回值:网络字节顺序的IP地址,是无符号的长整数
*/
- 2.inet_ntoa函数
char* inet_ntoa(struct in_addr in)
/*
入口参数in: 包含长整数IP地址的in_addr结构变量
返回值:指向点分十进制IP地址的字符串的指针
*/
listen():启动服务器,监听客户机端的连接请求
调用格式
int listen(SOCKET s,int backlog);
-
参数s:服务器端的套接字描述符,一般先进行绑定到熟知的服务器端口,要通过他监听来自客户端的连接请求,一般将这个套接字称为监听套接字
-
参数backlog:指定监听套接字的等待连接缓冲区队列的最大长度,一般为5
-
返回值:正确执行则返回0出错返回SOCKET_ERROR
-
函数功能:本函数适用于支持连接的套接字,在Internet通信域,仅用于流式套接字,并仅用于服务器端
accept():接收连接请求
调用格式
SOCKET accept(SOCKET s,struct sockaddr* addr,int * addrlen);
-
参数s:服务器端监听套接口描述符,调用listen()后,该套接口一直在监听连接
-
参数addr:可选参数,指向sockaddr结构的指针,该结构用来接收下面通信层所知的请求连接以方的套接字的网络地址
-
一个出口参数,用来但会下面通信层所指的对方连接实体的网络地址。
-
addr参数的实际格式由套接字创建时所产生的地址家族确定。
-