socket编程常见函数使用方法

socket知识

有了IP地址,socket可知道是与哪一台主机的哪一个进程通信

有了端口号,就知道是这个进程的哪一个套接字进行传输

应用进程使用描述符与它的套接字进行通信,也就是说一个进程创建一个套接字时就会返回一个套接字描述符
在这里插入图片描述

socket的地址信息最重要

已定义了结构sockaddr_in:,使用TCP/IP协议族的网络应用程序声明端点地址变量时,使用结构sockaddr_in

struct sockaddr_in 
{
    u_char sin_len; 	//地址长度
    u_char sin_family;	//地址族 TCP/IP的地址是AF_INET
    u_short sin_port;	//端口号
    struct in_addr sin_addr;	//IP地址
    char sin_zero[8];	//未用
}

socket api(WinSock)

windows环境下,先使用WSAStartup初始化Windows Sockets API,然后应用程序执行任务,最后执行WSACleanup释放所使用的Windows Sockets DLL占用的系统资源,接触与socket库的绑定。

WSAStartup

int WSAStartup(WORD wVersionRequested,LPWSADATA IpWSAData);

使用Socket的应用程序在使用Socket之前必须首先调用WSAStartup函数

两个参数:

  • 第一个参数指明程序请求使用WinSock版本,高位字节指明副版本、低位字节指明主版本

    • 0x102表示2.1版本
  • 第二个参数返回实际的WinSock的版本信息

    • 指向WSADATA结构的指针

例:使用2.1版本WinSock的程序代码段

wVersionRequested = MAKEWORD(2,1);
err = WSAStartup(wVersionRequested,&wsaData);

socket

该函数创建套接字

sd = socket(protofamily,type,proto);
  • 创建套接字

  • 操作系统返回套接字描述符(sd)

  • 第一个参数(协议族):protofamily = PF_INET (TCP/IP)

  • 第二个参数(套接字类型):

    • type = SOCK_STREAM,SOCK_DGRAM or SOCK_RAW(TCP/IP)
  • 第三个参数(协议号):0为默认

例:创建一个流套接字的代码段

struct protoent *p;
p = getprotobyname("tcp");
SOCKET sd = socket(PF_INET,SOCK_STREAM,p->p_proto);

不同类型的socket用于应用层与下层不同协议进行沟通。需要注意的是原始套接字SOCK_RAW需要拥有比较高的权限

在这里插入图片描述

TCP提供的服务特点:

可靠、面向连接、字节流传输、点对点

UDP提供的服务特点:

不可靠、无连接、数据报传输

Closesocket

int closesocket(SOCKET sd);
  • 关闭一个描述符为sd的套接字

  • 如果多个进程共享一个套接字,调用closesocket,将套接字引用计数减1,减至0才关闭

  • 一个进程中的多线程对一个套接字的使用无计数

    • 如果进程中的一个线程调用closesocket将一个套接字关闭,该进程中的其他线程也将不能访问该套接字
  • 返回值:0成功,SOCKET_ERROR不成功

bind

套接字创建的时候可能并没有地址 ,可以调用bind函数产生一个地址,或者说是用来绑定套接字的本地端点地址

int bind(sd,localaddr,addrlen);

端点地址其实就是IP地址 + 端口号

  • 参数

    • 套接字描述符 sd
    • 端点地址 localaddr,结构为sockaddr_in
    • 地址长度
  • 客户程序一般不必显式调用bind函数,因为操作系统会帮助我们设置客户端的端点地址

  • 对于服务器端需要调用,用来指定熟知端口号以及IP地址。如果服务器主机有多个网卡,产生多个ip地址,需要使用地址通配符,INADDR_ANY。表示在服务器运行的主机上任何一个可用ip地址都是可以用来传输的

listen

int listen(sd,queuesize);
  • 置服务器端的流套接字处于监听状态

    • 仅服务器端调用
    • 仅用于面向连接的流套接字
  • 设置连接请求队列(缓存)大小

  • 返回值: 成功为0,失败为SOCKET_ERROR

connect

connect(sd,saddr,saddrlen);
  • 客户程序调用connect函数来使客户套接字sd与特定计算机的特定端口saddr的套接字服务进行连接
  • 仅仅用于客户端
  • 可用于TCP客户端也可以用于UDP客户端
    • TCP客户端:建立了TCP连接
    • UDP客户端:只指定服务器端点地址

accept

newsock = accept(sd,caddr,caddrlen);
  • 服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道

    • 仅仅用于TCP套接字
    • 仅仅用于服务器
  • 利用新创建的套接字newsock与客户通信

为什么要这样做呢?因为TCP是点对点的,说明只能连接客户端和服务器的两个套接字。如果不这么做,就会导致TCP服务器在同一时刻只能为某一个客户提供服务,不能实现并发了。

在这里插入图片描述

send,sendto

send(sd,*buf,len,flags);
sendto(sd,*buf,len,flags,destaddr,addrlen);
  • send函数用于TCP套接字(客户与服务器)或调用了connect函数的UDP客户端套接字
    • sendto函数用于UDP服务器端套接字与为调用connect函数的UDP客户端套接字

recv,recvfrom

与上面的send、sendto对应

recv(sd,*buffer,len,flags);
recvfrom(sd,*buf,len,flags,senderaddr,saddrlen);
  • recv函数从TCP连接的另一端接收数据,或者从调用了connect函数的UDP客户端套接字接收服务器发来的数据
  • recvfrom函数用于从UDP服务器套接字与未调用connect函数的UDP客户端套接字接收对端数据

setsockopt,getsockopt

int setsockopt(int sd,int level,int optname,*optval,int optlen);
int getsockopt(int sd,int level,int optname,*optval,int socklen_t* optlen);
  • setsockopt()函数用来设置套接字sd的选项参数
  • getsockopt()函数用来获取任意类型、人影状态的套接口的选项当前值,并吧结果存入optval

简单小结

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拾牙慧者

欢迎请作者喝奶茶

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

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

打赏作者

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

抵扣说明:

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

余额充值