思路:
socket创建套接字之后->connect连接;
但是存在一个问题,connect之后如果端口是不通的,那么阻塞默认是会过 几十秒才会重新connect。
所以这时候我们要设置connect为非阻塞。
非阻塞的情况下:connect不管怎么样立即返回-1,所以不能当作判断的依据。所以要通过select判断是否可对这个服务器写消息,来判断是否该服务器的端口开放。
代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int main()
{
int sockClient = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSrv;
addrSrv.sin_addr.s_addr = inet_addr("47.107.53.238");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(22);
struct timeval tv = { 1,0 };//2s 超时
setsockopt(sockClient, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval));
int flag = fcntl(sockClient,3, 0);
flag |= 04000;
fcntl(sockClient, 4, flag);
int ret = 0;
while (1)
{
ret = connect(sockClient, (const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));
printf("connect ret:%d\n", ret);
fd_set rfd, wfd;
FD_ZERO(&wfd);
FD_SET(sockClient, &wfd);
ret = select(sockClient + 1, &rfd, &wfd, NULL, &tv);//注意必须是套接字最大值+1
printf("now ret:%d\n", ret);
if (FD_ISSET(sockClient, &wfd))
{
printf("open!\n");
break;
}
else
{
printf("connect failed...\n");
}
sleep(1);
}
//又重新设置成阻塞
flag = fcntl(sockClient, 3, 0);
flag &= ~04000;
fcntl(sockClient, 4, flag);
//可以发送数据测试一下,如果单纯为了测试是否连通,直接关闭套接字就行了
/*char buf[10] = { 0 };
for (unsigned int i = 0; i < 5; i++)
{
buf[i] = 'd';
}
ret = send(sockClient, buf, sizeof(buf), 0);
cout << "ret:" << ret <<"send success!"<< endl;
*/
close(sockClient);
return 0;
}