【tcp/ip模型】c.s模型(2)
@TOC
前言
创建Socket,绑定地址和端口号,监听,链接
提示:以下是本篇文章正文内容,下面案例可供参考
一、创建SOCKET
什么是SOCKET:将底层复杂的协议体系,执行流程,进行了封装,封装完的结果,就是一个SOCKET了
tcp/ip底层
也就是说,SOCKET是我们调用协议进行通信的 操作接口
所以SOCKET 很重要
意义:将复杂的协议过程与我们编程人员分开,我们直接操作一个简单SOCKET就行了,对于底层的协议 过程细节,完全不用知道,这就大大方便了我们。
本质:数据类型
就是一个unsigned int
但是这个是唯一的:就是ID
要和谁联系就要谁的socket
所以网络编程的函数都要socket
函数原型
SOCKET socket(
int af,//地址的类型
int type,//socket的类型
int protocol//协议的类型
);
其实就是宏
tcp/ip的固定填法为
socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
简写成socket(2,1,0)
返回值:
成功:返回可用SOCKET
失败:返回INVALID_SOCKET
获得错误码:WSAGetLasterror();
SOCKET Socket = socket(AF_INET, SOCK_STREAM, 0);//返回值成功为SOCKET
if (INVALID_SOCKET == Socket)
{
cout << "套接字创建出错!!!" << endl;
printf("套接字错误码:%d",WSAGetLasterror());
closesocket(Socket);//删除SOCKET
WSACleanup();//关闭网络库
return -1;
}
closesocket(SOCKET socket); 删除SOCKET
二、绑定地址和端口号bind
作用:给我们的socket绑定端口号与具体地址
地址:我们的电脑
端口号:每一种通信的端口号是唯一的
函数原型
int bind(
SOCKET s,
const sockaddr *addr,
int namelen
);
参数1:要绑定的SOCKET
参数2:sockaddr的结构体指针
参数3:参数2的大小
参数2详解:
sockaddr的成员:
地址类型
装IP地址
端口号
在sockaddr中 sa_data字符串数组其实是sockaddr_in中的sin_port,sin_addr,sin_zero
我们可以使用sizeof(sockaddr) sizeof(sockaddr_in)可知他们都是一样的字节数而且sa_data刚好装sin_port,sin_addr,sin_zero 所以我们可以通过强装把sockaddr_in装成sockaddr
(sockaddr*)&sock_in
SOCKADDR_IN的使用
成员1:和socket函数参数1一样
成员2:IP地址(inet_addr)
成员3:端口号(htons(端口号))
struct SOCKADDR_IN sock_in;
sock_in.sin_family = AF_INET;//和socket参数1一样
sock_in.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//IP 使用inet_addr
sock_in.sin_port = htons(12345);//端口号 使用htons函数
127.0.0.1是回送地址 本地回环地址 本地网络测试
本机ip:可以在控制台输入指令 ipconfig 就能看到了
端口号:0~65535
netstat -aon|findstr "12345"查看这个端口号是否被占
netstat -ano查看被使用的所有端口
在写客户端时:端口号和ip要和服务器的一样才可以
bind(Socket, (SOCKADDR*)&sock_in, sizeof(sock_in))
返回值
失败返回SOCKET_ERROR
if (bind_ == SOCKET_ERROR)
{
printf("bind绑定错误!!!");
int a = WSAGetLasterror();
WSACleanup();
closesocket(Socket);
return -1;
}
三、监听listen
作用:将套接字置于正在侦听传入连接的状态。
函数原型
int WSAAPI listen(//WSAAPI调用约定,不用写
SOCKET s,
int backlog
);
作用:将套接字置于正在侦听传入连接的状态。
参数1:服务器的SOCKET,也就是一开始的SOCKET
参数2:挂起连接队列的最大长度,一般填SOMAXCONN(让系统选最合适的)
返回值
失败:SOCKET_ERROR
int linten_ = listen(Socket,SOMAXCONN);
if(liten_==SOCKET_ERROR)
{
printf("listen监听错误!!!");
int a = WSAGetLasterror();
WSACleanup();
closesocket(Socket);
return -1;
}
四、接受链接accept
作用:accept函数允许在套接字上进行传入连接尝试。
listen监听客户端来的链接,accept讲客户端的信息绑定到一个socket上,也就是给客户端创建一个socket,通过返回值返回给我们服务端的socket
函数原型
SOCKET WSAAPI accept(
SOCKET s,
sockaddr *addr,
int *addrlen
);
参数1:服务器SOCKET
参数2:客户端的地址端口信息结构体(sockaddr*)
参数3:参数2的大小
参数2和参数3填NULL 就是不获取
返回值
成功:客户端SOCKET
失败:返回INVALID_SOCKET
SOCKET socket_KHD = appect(Socket,NULL,NULL);
if(socket_KHD==INVALID_SOCKET)
{
printf("appect链接错误!!!");
int a = WSAGetLasterror();
WSACleanup();
closesocket(Socket);
return -1;
}
accept调试
1、阻塞,同步:这个函数是阻塞的,没有客户端链接,那就一直卡在这儿,等着。
2、多个链接:一次只能一个,5个就要5次循环
缺点:必须要有客户端链接才可以进行下一步
总结
一、创建SOCKET
二、绑定地址和端口号bind
三、监听listen
四、接受链接accept
- 点赞
- 收藏
- 关注作者
评论(0)