客户端调用connect发起对服务器的socket的连接请求:
阻塞模式:
如果客户端socket描述符为阻塞模式则会一直阻塞到连接建立或者连接失败(注意阻塞模式的超时时间可能为75秒到几分钟之间)。
非阻塞模式:
如果客户端socket描述符为阻塞模式则会一直阻塞到连接建立或者连接失败(注意阻塞模式的超时时间可能为75秒到几分钟之间)。
判断连接成功没有的方法:
1.调用getpeername获取对端的socket地址.如果getpeername返回ENOTCONN,表示连接建立失败,然后用SO_ERROR调用getsockopt得到套接口描述符上的待处理错误;
2.调用read,读取长度为0字节的数据.如果read调用失败,则表示连接建立失败,而且read返回的errno指明了连接失败的原因.如果连接建立成功,read应该返回0;
  3.再调用一次connect.它应该失败,如果错误errno是EISCONN,就表示套接口已经建立,而且第一次连接是成功的;否则,连接就是失败的。
udp的情况
对于无连接的socket类型(SOCK_DGRAM),客户端也可以调用connect进行连接,此连接实际上并不建立类似SOCK_STREAM的连接,而仅仅是在本地保存了对端的地址,这样后续的读写操作可以默认以连接的对端为操作对象。
以下贴一段代码,该代码来源为腾讯开源的MSEC服务器的代码:显示正确的非阻塞使用方法
int MtFrame::connect(int fd, const struct sockaddr *addr, int addrlen, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
utime64_t start = mtframe->GetLastClock();
MicroThread* thread = mtframe->GetActiveThread();
utime64_t now = 0;
int n = 0;
mt_hook_syscall(connect);
while ((n = mt_real_func(connect)(fd, addr, addrlen)) < 0)
{
now = mtframe->GetLastClock();
if ((int)(now - start) > timeout)
{
errno = ETIME;
return -1;
}
// 此处为第二次调用connect函数的出口,表明连接连接成功。
if (errno == EISCONN) // ÒÑÁ¬½Ó, ·µ»Ø³É¹¦
{
return 0;
}
if (errno == EINTR) {
continue;
}
if (!((errno == EAGAIN) || (errno == EINPROGRESS))) {
MTLOG_ERROR("connect failed, errno: %d", errno);
return -2;
}
EpollerObj epfd;
epfd.SetOsfd(fd);
epfd.EnableOutput();
epfd.SetOwnerThread(thread);
if (!mtframe->EpollSchedule(NULL, &epfd, timeout)) {
return -3;
}
//此处返回后外层循环会继续 重新调用一次 connect。
}
return n;
}