网口

  • 格式:doc
  • 大小:219.00 KB
  • 文档页数:8

一、调用socket()建立一个套接口:/uptownBoy/articles/1488098.html与域参数只可以指定为PF_LOCAL的socketpair函数不同,socket函数可以用来创建任何协议族支持的套接口。

这个函数的概要如下:#include <sys/types.h>#include <sys/socket.h>int socket(int domain, int type, int protocol);这个函数接受三个输入参数:1 套接口的domain(要使用的协议族)2 套接口需要的type3 协议族要使用的特定的protocol如果调用成功,套接口将会作为函数的返回值返回。

与文件描述符相类似,如果值为零或是一个正值时,返回一个套接口。

如果出错则会返回-1。

当返回错误时,外部变量errno将会记录错误号。

协议:在socket函数中选择一个域值就是选择了一个要使用的协议族,一般有两个可选择的协议族PF_LOCAL和PF_INET:PF_LOCAL表明指定了一个本地UNIX套接口协议族。

PF_INET表明使用网络协议族套接口类型参数:socket函数调用中的套接口类型参数指明了一个套接口如何与我们的程序进行接口。

但是这并不是全部,因为这个参数与所选择的协议有关。

通常程序员会为套接口类型参数选择下列之中的一个:•SOCK_STREAM *•SOCK_DGRAM *•SOCK_S EQPACKET•SOCK_RAW标识为星号的两个是我们通常情况下会用到的两个。

SOCK_SEQPACKET通常用于非网络协议,例如X.25,或是广播协议AX.25。

(建议选SOCK_STREAM或 SOCK_SEQPACKET因为SOCK_STREAM套接口保证我们接收程序所接收到的数据就是我们写入的顺序。

同时SOCK_STREAM类型套接口的属性就是:数据是通过一对连接的套接口来传送的。

为了保证数据传输以及强制字节顺序,底层的协议使用了一对连接的套接口。

对于此时,我们只需要简单的知道SOCK_STREAM类型意味着必须在操作之前建立连接。

而SOCK_SEQPACKET与SOCK_STREAM相类似,但是却有一个明显的区别。

区别就在于SOCK_STREAM 不提供信息边界,但是SOCK_SEQPACKET提供。

例如,当使用X.25协议时,就会选择SOCK_SEQPACKET,每一个数据包会按着他原始写入的单元尺寸进行接收。

SOCK_SEQPACKET的特点是保留信息边界。

这个特性使其与SOCK_STREAM类型相区别。

接收的数据是按着所发送的顺序进行精确接收。

所有的数据假定无误的发送到接收端。

如果在合理的自动修复尝试后不可以传输,就会向发送端与接收端报告错误。

数据是在一对连接的套接口上进行传输的。

)选择协议:使用PF_LOCAL和SOCK_STREAM正确socket函数调用如下所示:int s;s = socket(PF_LOCAL,SOCK_STREAM,0);if ( s == -1 )这会创建一个允许一个进程与本地机器上的另一个进程进行通信的流式套接口。

使用PF_INET和SOCK_STREAM现在,对于PF_INET域的socket函数协议参数指定为零时,内核会选择IPPROTO_TCP。

这会使得套接口使用TCP/IP协议。

TCP/IP 指令的TPC部分是建立在IP层上的传输层协议。

这会提供数据包顺序化,错误控制以及修复。

简言之,TCP使得使用网络协议来提供一个流式套接口成为可能。

如下面的例子所示,大多数的程序会选择简单的将协议参数指定为零,从而允许内核选择合适的协议:int s;s = socket(PF_INET,SOCK_STREAM,0);if ( s == -1 )perror("socket()");将socket函数中的协议参数指定零意味着使用TCP/IP协议。

然而,如果我们希望完全的控制,或是我们担心将来的内核默认协议不合适,我们可以显式的选择协议:int s;s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);if ( s == -1 )perror("socket()");使用PF_LOCAL和SOCK_DGRAMint s;s = socket(PF_LOCAL,SOCK_DGRAM,0);if ( s == -1 )perror("socket()");数据报套接口对于PF_LOCAL套接口是很合适的,因为他们更可靠,并且他们可以保留信息边界。

他们并不会在网络传输中丢失错误,而PF_INET数据报会,因为他们保留在本地主机内部。

然而,我们必须了解由内核缓冲区的缺少会造成PF_LOCAL包的丢失,尽管这很少会发生。

使用PF_INET和SOCK_DGRAM要创建一个UDP套接口,我们将协议参数指定为零。

如下面的例子所示:int s;s = socket(PF_INET,SOCK_DGRAM,0);if ( s == -1 )perror("socket()");然而如果我们更喜欢显示的指定UDP协议,我们可以用下面的例子方式:int s;s = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);if ( s == -1 )二、bind() bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/断口号)。

简述:将一本地地址与一套接口捆绑。

#include <winsock.h>int PASCAL FAR bind( SOCKET s, const struct sockaddr FAR* name, int namelen);s:标识一未捆绑套接口的描述字。

name:赋予套接口的地址。

sockaddr 结构定义如下:struct sockaddr{u_short sa_family;char sa_data[14];};namelen:name 名字的长度。

三、listen()简述:创建一个套接口并监听申请的连接.#include <winsock.h>int PASCAL FAR listen( SOCKET s, int backlog);S:用于标识一个已捆绑未连接套接口的描述字。

backlog:等待连接队列的最大长度。

注释:为了接受连接,先用 socket()创建一个套接口,然后用 listen()为申请进入的连接建立一个后备日志,然后便可用 accept()接受连接了。

listen()仅适用于支持连接的套接口,如SOCK_STREAM 类型的。

套接口 s 处于一种“变动”模式,申请进入的连接请求被确认,并排队等待被接受。

这个函数特别适用于同时有多个连接请求的服务器;如果当一个连接请求到来时,队列已满,那么客户将收到一个 WSAECONNREFUSED 错误。

当没有可用的描述字时,listen()函数仍试图正常地工作。

它仍接受请求直至队列变空。

当有可用描述字时,后续的一次 listen()或 accept()调用会将队列按照当前或最近的“后备日志”重新填充,如有可能的话,将恢复监听申请进入的连接请求。

四、accept()简述:在一个套接口接受一个连接。

#include <winsock.h>SOCKET PASCAL FAR accept( SOCKET s, struct sockaddr FAR* addr,int FAR* addrlen);s:套接口描述字,该套接口在 listen()后监听连接。

addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。

Addr 参数的实际格式由套接口创建时所产生的地址族确定。

addrlen:(可选)指针,指向存有 addr 地址长度的整形数。

注释:本函数从 s 的等待连接队列中抽取第一个连接,创建一个与 s 同类的新的套接口并返回句柄。

如果队列中无等待连接,且套接口为非阻塞方式,则 accept()阻塞调用进程直至新的连接出现。

如果套接口为非阻塞方式且队列中等待连接,则 accept()返回一错误代码。

已接受连接的套接口不能用于接受新的连接,原套接口仍保持开放。

addr 参数为一个返回参数,其中填写的是为通讯层所知的连接实体地址。

addr 参数的实际格式由通讯时产生的地址族确定。

addrlen 参数也是一个返回参数,在调用时初始化为 addr 所指的地址空间;在调用结束时它包含了实际返回的地址的长度(用字节数表示)。

该函数与SOCK_STREAM 类型的面向连接的套接口一起使用。

如果 addr 与 addrlen 中有一个为零 NULL,将不返回所接受的套接口远程地址的任何信息。

返回值:如果没有错误产生,则 accept()返回一个描述所接受包的 SOCKET 类型的值。

否则的话,返回 INVALID_SOCKET 错误,应用程序可通过调用 WSAGetLastError()来获得特定的错误代码。

addrlen 所指的整形数初始时包含 addr 所指地址空间的大小,在返回时它包含实际返回地址的字节长度。

五、connect()简述:建立与一个端的连接。

#include <winsock.h>int PASCAL FAR connect( SOCKET s, const struct sockaddr FAR* name, int namelen);s:标识一个未连接套接口的描述字。

name:欲进行连接的端口名。

namelen:名字长度。

注释:本函数用于创建与指定外部端口的连接。

s 参数指定一个未连接的数据报或流类套接口。

如套接口未被捆绑,则系统赋给本地关联一个唯一的值,且设置套接口为已捆绑。

请注意若名字结构中的地址域为全零的话,则 connect()将返回WSAEADDRNOTAVAIL 错误。

对于流类套接口(SOCK_STREAM 类型),利用名字来与一个远程主机建立连接,一旦套接口调用成功返回,它就能收发数据了。

对于数据报类套接口(SOCK_DGRAM 类型),则设置成一个缺省的目的地址,并用它来进行后续的 send()与 recv()调用。

返回值:若无错误发生,则 connect()返回 0。

否则的话,返回 SOCKET_ERROR 错误,应用程序可通过 WSAGetLastError()获取相应错误代码。

对阻塞套接口而言,若返回值为 SOCKET_ERROR则应用程序调用 WSAGetLsatError()。