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


前言

创建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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人才程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值