【tcp/ip模型】c.s模型(2)

举报
人才程序员 发表于 2023/10/29 20:37:40 2023/10/29
【摘要】 @TOC 前言 创建Socket,绑定地址和端口号,监听,链接提示:以下是本篇文章正文内容,下面案例可供参考 一、创建SOCKET什么是SOCKET:将底层复杂的协议体系,执行流程,进行了封装,封装完的结果,就是一个SOCKET了tcp/ip底层也就是说,SOCKET是我们调用协议进行通信的 操作接口所以SOCKET 很重要意义:将复杂的协议过程与我们编程人员分开,我们直接操作一个简单SOC...

@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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。