0
点赞
收藏
分享

微信扫一扫

socket编程常见函数使用方法

socket知识

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

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

应用进程使用描述符与它的套接字进行通信,也就是说一个进程创建一个套接字时就会返回一个套接字描述符
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需要拥有比较高的权限

socket编程常见函数使用方法_socket_02

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服务器在同一时刻只能为某一个客户提供服务,不能实现并发了。

socket编程常见函数使用方法_客户端_03

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

简单小结

socket编程常见函数使用方法_客户端_04


举报

相关推荐

0 条评论