socket编程学习笔记:部分函数用法以及accept函数问题

socket()函数:

socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个sockfd套接字,它唯一标识一个socket。创建socket的时候,也可以指定不同的参数创建不同的socket套接字;
socket函数的三个参数
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET(ipv4地址)、AF_INET6(ipv6地址)、AF_LOCAL、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址;

type:指定socket类型。常用的socket类型有,SOCK_STREAM(TCP协议)、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET等等;

protocol:指定协议。常用的协议有,IPPROTO_TCP(TCP传输协议)、IPPTOTO_UDP(UDP传输协议),IPPROTO_SCTP(STCP传输协议)
等等,type和protocol并不是可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默
认协议;

bind()函数:

bind是捆绑的意思,通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器,个人理解,bind函数就是将ip地址和端口号绑定在创建的socket套接字里;在这里插入图片描述
sockfd:即socket套接字,它是通过socket()函数创建的,仅仅标识唯一的一个socket;

addr:一个const struct sockaddr *类型的指针,指向绑定给sockfd的协议地址。创建socket时的地址协议族不同,导致地址不同,但可以通过强制转换后赋值给sockaddr这种类型的指针((struct sockaddr *)&server_addr;);

addrlen:对应的是sockaddr结构体的大小,即addr里面绑定服务器端地址等信息的结构体的长度,一般为sizeof(sockaddr);

listen()函数:

socket()函数创建的socket套接字默认是一个主动类型的,在服务端,创建socket,bind后需要调用listen函数监听是否有客户端连接,该函数将socket套接字变为被动类型的,等待客户的连接;
在这里插入图片描述
sockfd: 即socket套接字,socket()系统调用创建的要监听的描述字;

backlog: 相应socket可以在内核里排队的最大连接个数;

accept()函数:

服务端调用socket()、bind()、listen()函数之后,就会监听指定的socket地址,服务器之后就会调用accpet()接受来自客户端的连接请求,这个函数默认是一个阻塞函数,如果没有客户端连接服务器该程序将一直停滞,直到有一个客户端调用connect()函数就会触发服务器的accept()返回,这时整个服务器客户端链接就建立完成;
在这里插入图片描述
sockfd: 即socket套接字,socket()系统调用创建的要监听的套接字;

注:accept函数在接受一个客户端连接请求后会返回一个新的sockfd,此sockfd和socket、bind调用时返回的sockfd并不是一个,此sockfd用于服务端和客户端之间的通信,不同的客户端之间的sockfd也不同;

addr::一个const struct sockaddr *类型的指针,用于返回客户端的协议地址,这个地址里包含有客户端的IP和端口信息等,和bind函数里第二个参数使用方法一样;

addrlen: 这个参数是一个传入传出参数,传入addrlen值的大小,当有客户端请求连接时,函数会根据addrlen的值大小往 sockaddr结构体里填入数据,值的大小会影响填入数据是否正确,(需要定义socklen_t addrlen;相当于unsigned int类型),可以使其等于sockaddr结构体的大小,addrlen=sizeof( sockaddr),也就是对其进行初始化;函数返回时返回包含对等地址的实际数值(一般为服务器地址),所以每次和客户端建立连接accept函数返回后最好都对其进行初始化,因为要改变值,所以为指针类型,传入地址;

如果不初始化addrlen,在客户端连接服务器时由于addrlen是随机值,sockaddr结构体里的数据填入不正确,服务器端可能会出现以下问题:
在这里插入图片描述

connect()函数:

客户端调用socket()创建sockfd之后,如果客户端调用connect()发出连接请求,服务端就会接收到这个请求并使accept()返回,accept()返回的新的sockfd就是对应到该客户的连接,通过这两个sockfd(客户端connect的sockfd和服务器端accept返回的sockfdfd)就可以实现客户端和服务器端的相互通信。
在这里插入图片描述
sockfd: 即socket套接字,客户端调用socket()创建套接字;

addr: 要连接的服务器的信息,包含服务器的IP地址和端口等信息,保存在相应的结构体里;

addrlen: 对应的是sockaddr结构体的大小,即addr里面绑定服务器端地址等信息的结构体的长度,一般为sizeof(sockaddr);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值