
bool CRemoteLink::Connect()
{
OnDisconnected() // 如果已经连接,则断开
if(!m_bUseProxy)
{
m_iConnStatus = SS_CONNECTING // 正在连接状态
GNTRACE ("开始连接到远程服务器[%s][%ld]...\n", m_strip.c_str(), m_port)
// 建立套接字, 准备连接到服务器
m_socket = ::socket(AF_INET, SOCK_STREAM, 0)
if (socket <0) {
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE, MSG_SE_CREATE)
return false
}
// 设为异步 *** 作方式
unsigned long on = 1
if (::ioctlsocket(m_socket, FIONBIO, &on) <0) {
::closesocket(m_socket)
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CREATE, MSG_SE_CREATE)
return false
}
sockaddr_in addr
memset(&addr, 0, sizeof(addr))
addr.sin_family = AF_INET
addr.sin_addr.s_addr = inet_addr(m_strip.c_str())
addr.sin_port = htons(m_port)
int rt
rt = ::connect(m_socket, (sockaddr *) &addr, sizeof(addr))
if (rt == 0) {
OnConnected()
return true
}
// ==================================================================
timeval to
// 首先建立连接
fd_set wfds
fd_set efds
FD_ZERO(&wfds)
FD_ZERO(&efds)
// test shutdown event each 100ms.
to.tv_sec = 0
// CONNECT_TIMEOUT
to.tv_usec = 100000
int it = 0
while(!m_meShutdown.Wait(0) &&!m_meConnStop.Wait(0))
{
FD_SET(m_socket, &wfds)
FD_SET(m_socket, &efds)
int n = select(m_socket + 1, NULL, &wfds, &efds, &to)
if (n >0) {
if(FD_ISSET(m_socket, &wfds))
{
OnConnected()
return true
}
else
{
//int err = ::WSAGetLastError()
//const char* msg = GetLastErrorMessage(err)
GNTRACE ("CRemoteLink::Connect : connection attempt failed!\n")
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_CONN, MSG_SE_CONN)
break
}
} else if (n <0) { // Select Error
int err = ::WSAGetLastError()
const char* msg = GetLastErrorMessage(err)
GNTRACE ("CRemoteLink::Connect : Select Error.[%d] - %s\n", err, msg)
if(m_pCallBack)
m_pCallBack->OnSocketError(err, msg)
break
}
else
{
it += 100
if(it >30000) // 连接超时 -- (30S)
{
GNTRACE ("CRemoteLink::Connect : Time out.\n")
if(m_pCallBack)
m_pCallBack->OnSocketError(SE_TIMEOUT, MSG_SE_TIMEOUT)
break
}
}
}
if(m_meConnStop.Wait(0))
{
GNTRACE("连接过程进行时被取消。\n")
}
}
else
{
// 通过代理服务器连接
那就必须要精通 Linux 的网络协议的 socket 编程了。这个肯定是可以检测网络状态的。具体的 server/client 编程模式,可以参考《TCP/IP 协议详解》一书(上、下册)。unsigned int dir(char * server) {int sck//套接字变量
struct sockaddr_in serv_adr//远程主机的地址
struct hostent *host //指向远程主机的指针
unsigned char databuf[FILEBUF_SIZE]//数据
int bytes = 0, bytesread = 0//字节数,读取到的字节数
host = gethostbyname(server)//根据远程主机的主机名,得到指向远程主机的指针
if (host == (struct hostent *) NULL) { //如果得到指向远程主机的指针失败,报告错误,并返回
perror("gethostbyname failed")
return 0
}memset(&serv_adr, 0, sizeof(serv_adr))//初始化远程主机的地址,结构体内所有成员清零
serv_adr.sin_family = AF_INET //设置地址类型
memcpy(&serv_adr.sin_addr, host->h_addr, host->h_length)//取出指向远程主机的指针中包含的地址信息,赋给远程主机地址变量
serv_adr.sin_port = htons(SERVICE_PORT)//设置端口号,比如http服务对应80端口,ftp对应21端口
if ((sck = socket(AF_INET, SOCK_STREAM, 0)) <0) { //如果建立TCP协议的套接字失败,报告错误,并返回
perror("error on socket()")
return 0
}
if (connect(sck, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) <0) {//如果使用该套接字连接到远程主机失败,报告错误,并返回
perror("error on connect()")
return 0
}write(sck, "DI\n\n", 4)//连接成功,发送内容为"DI\n\n"的消息,远程主机收到该消息,解析后生成目录列表,并将目录列表信息传递回来
printf("Remote directory listing:\n")//输出提示信息“远程主机正在生成目录列表”
while ((bytes = read(sck, databuf, FILEBUF_SIZE)) >0) { //从套接字的数据流中读取远程主机的返回信息(即目录列表),每次读取FILEBUF_SIZE个字节,直到全部读取完毕
write(fileno(stdout), databuf, bytes)//将每次读到的数据,输出到标准输出流(stdout),即屏幕上
bytesread += bytes//接收到的字节数累加
}
close(sck)/* Close the socket */ //通信完成,关闭套接字,关闭连接
return bytesread//返回读取到的字节数(即远程主机返回的信息的大小)
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)