网络IPC:套接字之建立连接
如果处理的是面向连接的网络服务(SOCK_STREAM或SOCK_SEQPACKET),在开始交换数据以前,需要在请求服务的进程套接字(客户端)和提供服务的进程套接字(服务器)之间建立一个连接。客户端可以用connect建立一个连接。
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t len);
返回值:若成功则返回0,出错则返回-
在connect中所指定的地址是想与之通信的服务器地址。如果sockfd没有绑定到一个地址,connect会给调用者绑定一个默认地址。
当连接一个服务器时,出于一些原因,连接可能失败。要连接的机器必须开启并且正在运行,服务器必须绑定到一个想与之连接的地址,并且在服务器的等待连接队列中应有足够的空间。因此,应用程序必须能够处理connect返回的错误,这些错误可能由一些瞬时变化条件引起。
实例
程序清单16-2显示了一种如何处理瞬时connect错误的方法。这在一个负载很重的服务器上很有可能发生。
#include "apue.h"
#include <sys/socket.h> #define MAXSLEEP 128 int
connect_retry(int sockfd, const struct sockaddr *addr, socklen_t len)
{
int nsec; /*
* Try to connect with exponential backoff.
*/
for(nsec = ; nsec <= MAXSLEEP; nsec <<= )
{
if(connect(sockfd, addr, alen) == )
{
/*
* Connection accepted.
*/
return();
} /*
* Delay before trying again.
*/
if(nsec <= MAXSEELP/)
sleep(nsec);
}
return(-);
}
这个函数使用了名为指数补偿(exponential backoff)的算法。如果调用connect失败,进程就休眠一小段时间后再尝试,每循环一次增加每次尝试的延迟,直到最大延迟为2分钟。
如果套接字描述符处于非阻塞模式下,那么在连接不能马上建立时,connect将会返回-1,并且将errno设为特殊的错误码EINPROGRESS。应用程序可以使用poll或select来判断文件描述符何时可写。如果可写,连接完成。
函数connect还可以用于无连接的网络服务(SOCK_DGRAM)。这看起来有点矛盾,实际上却是一个不错的选择。如果在SOCK_DGRAM套接字上调用connect,所有发送报文的目标地址设为connect调用中所指定的地址,这样每次传送报文时就不需要再提供地址。另外,仅能接收来自指定地址的报文。
服务器调用listen来宣告可以接受连接请求。
#include <sys/socket.h>
int listen(int sockfd, int backlog);
返回值:若成功则返回0,出错则返回-
参数backlog提供了一个提示,用于表示该进程所要入队的连接请求数量。其实际值由系统决定,但上限由<sys/socket.h>中SOMAXCONN指定。
一旦队列满,系统会拒绝多余连接请求,所以backlog的值应该基于服务器期望负载和接受连接请求与启动服务的处理能力来选择。
一旦服务器调用了listen,套接字就能接收连接请求。使用函数accept获得连接请求并建立连接。
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len);
返回值:若成功则返回文件(套接字)描述符,出错则返回-
函数accept所返回的文件描述符是套接字描述符,该描述符连接到调用connect的客户端。这个新的套接字描述符和原始套接字(sockfd)具有相同的套接字类型和地址族。传给accept的原始套接字没有关联到这个连接,而是继续保持可用状态并接受其他连接请求。
如果不关心客户端标识,可以将参数addr和len设为NULL;否则,在调用accept之前,应将参数addr设为足够大的缓冲区来存放地址,并且将len设为指向代表这个缓冲区大小的整数的指针。返回时,accept会在缓冲区填充客户端的地址并且更新指针len所指向的整数为该地址的大小。
如果没有连接请求等待处理,accept会阻塞直到一个请求到来。如果sockfd处于非阻塞模式,accept会返回-1并将errno设置为EAGAIN或EWOULDBLOCK。
如果服务器调用accept并且当前没有连接请求,服务器会阻塞直到一个请求到来。另外,服务器可以使用poll或select来等待一个请求的到来。在这种情况下,一个带等待处理的连接请求套接字会以可读的方式出现。
实例
程序清单16-3显示了一个服务器进程用以分配和初始化套接字的函数。
程序清单16-3 服务器初始化套接字端点
#include "apue.h"
#include <errno.h>
#include <sys/socket.h> int
initserver(int type, const struct sockaddr *addr, socklen_t alen, int qlen)
{
int fd;
int err = ; if((fd = socket(addr->sa_family, type, )) < )
return(-);
if(bind(fd, addr, alen) < )
{
err = errno;
goto errout;
}
if(type == SOCK_STREAM || type == SOCK_SEQPACKET)
{
if(listen(fd, qlen) < )
{
err = errno;
goto errout;
}
}
return(fd); errout:
close(fd);
errno = err;
return(-);
}
本篇博文内容摘自《UNIX环境高级编程》(第2版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。
网络IPC:套接字之建立连接的更多相关文章
- Unix环境高级编程(十七)网络IPC套接字
通过网络套接字可以使得不同计算机上运行的进程相互通信. 1.创建套接字 #include <sys/socket.h> Int socket( int domain, int type, ...
- 第十六章:网络IPC 套接字
一.IP地址和端口 套接字接口可以用于计算机间通信.目前计算机间使用套接字通讯需要保证处于同一网段. 为了查看是否处于同一网段,我们可以使用IP地址判断. IP地址是计算机在网络中的唯一标识.IP地址 ...
- Java网络编程--套接字Socket
一.套接字Socket IP地址标志Internet上的计算机,端口号标志正在计算机上运行的进程(程序). 端口号被规定为一个16位的0--65535之间的整数,其中,0--1023被预先定义的服务通 ...
- 网络编程 套接字socket TCP UDP
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
- UNIX网络编程——套接字选项(心跳检测、绑定地址复用)
/* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 */ void setKeepAlive( in ...
- c 网络与套接字socket
我们已经知道如何使用I/O与文件通信,还知道了如何让同一计算机上的两个进程进行通信,这篇文章将创建具有服务器和客户端功能的程序 互联网中大部分的底层网络代码都是用C语言写的. 网络程序通常有两部分组成 ...
- 网络---中断套接字Socket
package socketpack_2; import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.even ...
- UNIX网络编程——套接字选项
http://www.educity.cn/linux/1241288.html 有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项. int getsockopt( ...
- UNIX网络编程——套接字选项(SO_RCVBUF和SO_SNDBUF)
有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项. int getsockopt(int sockfd,int level,int optname,void *op ...
随机推荐
- 用duilib制作仿QQ2013动态背景登录器
转载请说明原出处,谢谢~~ 在上一篇博客里,我修复了CActiveXUI控件的bug,从而可以使用flash动画来制作程序的背景,这篇博客说明一下应该怎么使用CActiveXUI控件创建透明无窗体的背 ...
- C++实现离散余弦变换(参数为二维指针)
C++实现离散余弦变换(参数为二维指针) 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现.在实现论文 ...
- HDU5727 Necklace
http://acm.hdu.edu.cn/showproblem.php?pid=5727 题意:n个珠子,每个珠子有阴阳两种属性,且阴的一定和阳的紧邻,排成一个环:m行,每行两个数,表示阳性x珠子 ...
- Linux下用Intel编译器编译安装NetCDF-Fortan库(4.2以后版本)
本来这个问题真的没必要写的,可是真的困扰我太久%>_<%,决定还是记录一下. 首先,最权威清晰的安装文档还是官方的: Building the NetCDF-4.2 and later F ...
- SQL中以count及sum为条件的查询
在开发时,我们经常会遇到以“累计(count)”或是“累加(sum)”为条件的查询.比如user_num表: id user num 1 a 3 2 a 4 3 b 5 4 b 7 例1:查询出现 ...
- PhoneGap搭建运行环境(3.2版本)
一. 1.准备环境nodejs(http://nodejs.org/download/) 2.ant(http://ant.apache.org/bindownload.cgi) 3.Android ...
- log4j2使用总结
一.Log4j有三个主要的组件:Loggers,Appenders和Layouts,这里可简单理解为日志级别,日志要输出的地方和日志格式 1. Logger Logger的日志级别有6级,分别是TRA ...
- 【转】iOS 硬件授权检测:定位服务、通讯录、日历、提醒事项、照片、蓝牙共享、麦克风、相机等
iOS系统版本的不断升级的前提,伴随着用户使用设备的安全性提升,iOS系统对于App需要使用的硬件限制也越来越严格,App处理稍有不妥,轻则造成功能不可用用户还不知道,重则会造成App Crash. ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- Light oj 1197 - Help Hanzo (素数筛技巧)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 给你a和b求a到b之间的素数个数. 先在小区间素数筛,大区间就用类似素数筛的想法 ...