Socket简介

[quote][b]A network socket [/b]is an endpoint of an inter-process communication flow across a computer network. Today, most communication between computers is based on the Internet Protocol; therefore most network sockets are Internet sockets.
[b]A socket API [/b]is an application programming interface (API), usually provided by the operating system, that allows application programs to control and use network sockets. Internet socket APIs are usually based on the Berkeley sockets standard.
[b]A socket address[/b] is the combination of an IP address and a port number, much like one end of a telephone connection is the combination of a phone number and a particular extension. Based on this address, internet sockets deliver incoming data packets to the appropriate application process or thread.[/quote]
[b]inter-process communication[/b]的机制:
[list]
[*]1、管道
[*]2、先进先出(FIFO)
[*]3、消息队列
[*]4、信号量
[*]5、共享内存
[*]6、套接字(socket)?
[/list]
[b]Socket主要用于进程间通信(IPC)。[/b]
访问套接字也需要描述符。类似文件描述符一样。套接字描述符(sockfd)在Unix系统是用文件描述符实现的。
[b]1、socket函数:[/b]

#include<sys/socket.h>
int socket(int domain, int type, int protocol)

[b]domain[/b]即[b]AF(address family)[/b]套接字通信域
[table]
|AF_INET IPv4|
|AF_INET6 IPv6|
|AF_UNIX UNIX域|
|AF-UNSPEC 未指定|
[/table]
[b]type[/b]即:
[table]
|SOCK_DGRAM 长度固定的,无连接的不可靠报文传递|
|SOCK_STREAM 有序、可靠、双向的面向连接字节流|
|SOCK_RAW IP协议的数据报接口|
[/table]
[quote]Socket types
There are several Internet socket types available:
* [b]Datagram sockets[/b], also known as connectionless sockets, which use User Datagram Protocol (UDP)
* [b]Stream sockets[/b], also known as connection-oriented sockets, which use Transmission Control Protocol (TCP) or Stream Control Transmission Protocol (SCTP).
* [b]Raw sockets (or Raw IP sockets)[/b], typically available in routers and other network equipment. Here the transport layer is bypassed, and the packet headers are made accessible to the application.
There are also non-Internet sockets, implemented over other transport protocols, such as Systems Network Architecture (SNA).[2] See also Unix domain sockets (UDS), for internal inter-process communication.[/quote]
[b]protocol[/b]:
[list]
[*]IPPROTO_TCP
[*]IPPROTO_UDP
[*]IPPROTO_SCTP
[/list]
[b]2、bind函数:[/b]
把一个本地协议地址赋予一个socket
服务器需要给客户端请求的socket绑定一个众所周知的address。

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t len);

[b]3、connect函数(client)[/b]

#include <sys/socket.h>
int connection(int sockfd, const struct sockaddr *addr, socklen_t len);

第二个、第三个参数分别是指向socket地址结构的指针和该结构的大小。
如果是tcp socket的话conntct函数将激发tcp的三路握手过程。
[b]4、listen函数[/b]
服务器调用listen来宣告可以接受连接请求

#include <sys/socket.h>
int listen(int sockfd, int backlog);

listen函数仅由TCP服务器调用,它做两件事情:
第一、当socket函数创建一个socket时,它被假设为一个主动套接字,也就是说它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应接收该套接字的请求。
其次、本函数第二个参数规定了内核应该为相应套接字排队的最大连接个数。
[b]5、accept函数[/b]
用于从已完成连接队列对头返回下一个已完成连接。
一旦服务器调用了listen,socket就能接收connect请求。

#include <sys/socket.h>
int accept(int socked, struct sockaddr * restrict addr, socklen_t * restrict len);

[b]6、close函数[/b]
用来关闭套接字,并终止TCP连接。

#include <sys/socket.h>
int close(int sockfd);

[b]7、传输和接收函数[/b]
a、send

#include <sys/socket.h>
asize_t send(int socked, const void *buf, size_t nbytes, int flags);

b、sendto
和send类似,区别在于sendto允许在无连接的socket上制定一个目标地址

#include <sys/socket.h>
asize_t sendto(int socked, const void *buf, size_t nbytes, int flags, const struct sockaddr *destaddr, socklen_t destlen);

c、sendmsg

#include <sys/socket.h>
asize_t sendmsg(int socked, const struct msghdr *msg, int flags);

d、recv

#include <sys/socket.h>
asize_t recv(int socked, const void *buf, size_t nbytes, int flags);

e、recvfrom 可以得到数据发送者的源地址

#include <sys/socket.h>
asize_t recvfrom(int socked, void *restrict buf, size_t len, int flags,struct sockaddr *restrict addr,socklen_t *restrict addrlen);

f、recvmsg为了将接收到的数据送入多个缓存区,或者想接收辅助数据可以使用recvmsg

#include <sys/socket.h>
asize_t recvmsg(int socked, const struct msghdr *msg, int flags);

[b]8、socket选项[/b]
setsockopt

#include <sys/socket.h>
int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);

getsockopt

#include <sys/socket.h>
int getsockopt(int sockfd, int level, int option, void *restrict val, socklen_t *restruct lenp);

[b]others:[/b]
可以调用getsockname来发现绑定到一个套接字的地址:

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr * restrict addr, socklen_t * restrict alenp);

通过调用getpeername来找到对方地址:

#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr * restrict addr, socklen_t * restrict alenp);

除了还会返回对方的地址外,两个函数一样。
套接字通信是双向的,可以采用函数shutdown来禁止套接字上的输入/输出

#include <sys/socket.h>
int shutdown(int sockfd, int how);

options:
[list]
[*]SHUT_WR
[*]SHUT_RD
[*]SHUT_RDWR
[/list]
[b]能够close套接字,为什么还使用shutdown呢?[/b]
理由:
首先,close只有在最后一个活动引用被关闭时才释放网络端点。这意味着如果复制一个socket(ex:dup)socket直到关闭了最后一个引用它文件描述符之后才会被释放。而shutdown允许使一个socket处于不活动状态,无论引用它的sockfd多少。
其次,有时只关闭socket双向传输中的一个方向会很方便。

[quote]这个列表是一个Berkeley套接字API库提供的函数或者方法的概要:
* socket() 创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。
* bind() 一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
* listen() 用于服务器端,使一个绑定的TCP套接字进入监听状态。
* connect() 用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
* accept() 用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
* send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用于往/从远程套接字发送和接受数据。
* close() 用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。
* gethostbyname()和gethostbyaddr() 用于解析主机名和地址。
* select() 用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。
* poll() 用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。
* getsockopt() 用于查询指定的套接字一个特定的套接字选项的当前值。
* setsockopt() 用于为指定的套接字设定一个特定的套接字选项[/quote]

参考资料:
http://en.wikipedia.org/wiki/Network_socket
http://en.wikipedia.org/wiki/Inter-process_communication
http://zh.wikipedia.org/wiki/Berkeley%E5%A5%97%E6%8E%A5%E5%AD%97
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值