Chinaunix
标题:
c语言中socket的问题
[打印本页]
作者:
nmcny
时间:
2004-01-27 20:55
标题:
c语言中socket的问题
我在sco unix 下建立了一个socket 的stream连接,使用connect函数时,如何设置超时时间
作者:
hsia
时间:
2004-01-28 02:14
标题:
c语言中socket的问题
可以在论坛内搜一下,然后再提问。
作者:
forest077
时间:
2004-01-29 18:20
标题:
c语言中socket的问题
可以使用alarm函数设置超时时间。
作者:
FH
时间:
2004-01-29 20:36
标题:
c语言中socket的问题
使用non-blocking I/O比用超时更好,不妨试试看。
作者:
nmcny
时间:
2004-01-30 09:42
标题:
c语言中socket的问题
无阻塞io是不是只有在调用connect函数成功后才能使用,我想知道怎么设置connect函数的超时时间,一般的话,连接一台不能提供服务器功能的机器会需要大概3分钟的时间,才能得到connect不成功的返回值.原来我想用线程来实现延时功能,但是在sco unix下没找到libthread库,是不是此操作系统下不支持,还是库名不对,望各位大侠帮忙!
作者:
wjywhl
时间:
2004-01-30 11:30
标题:
c语言中socket的问题
SCO不支持Thread
作者:
forest077
时间:
2004-01-30 17:57
标题:
c语言中socket的问题
在connect之前调用一下alarm设置一下超时时间,在connect之后调用一下alarm(0)清空定时器即可。
作者:
kys2002
时间:
2004-01-31 14:42
标题:
c语言中socket的问题
用select函数吧
作者:
nmcny
时间:
2004-01-31 21:21
标题:
c语言中socket的问题
forest077你的方法应该可以,我试一试,多谢
作者:
mills
时间:
2004-02-02 09:37
标题:
c语言中socket的问题
网络编程第一卷上有例子的
作者:
jianyan
时间:
2004-02-02 22:22
标题:
c语言中socket的问题
以下是PHP源代码中FTP的东东,自已看一下就知道了
/*
* Fills the any (wildcard) address into php_sockaddr_storage
*/
void ftp::any_addr(int family, sockaddr_storage *addr, unsigned short port){
memset(addr, 0, sizeof(sockaddr_storage));
switch (family) {
case AF_INET: {
struct sockaddr_in *sin = (struct sockaddr_in *) addr;
sin->;sin_family = AF_INET;
sin->;sin_port = htons(port);
sin->;sin_addr.s_addr = htonl(INADDR_ANY);
break;
}
}
}
/*
* Returns the size of struct sockaddr_xx for the family
*/
int ftp::sockaddr_size(sockaddr_storage *addr){
switch (((struct sockaddr *)addr)->;sa_family) {
case AF_INET:
return sizeof(struct sockaddr_in);
#ifdef AF_UNIX
case AF_UNIX:
return sizeof(struct sockaddr_un);
#endif
default:
return 0;
}
}
int ftp::connect_nonb(int sockfd,const struct sockaddr *addr,
socklen_t addrlen, struct timeval *timeout){
int flags;
int n;
int error = 0;
socklen_t len;
int ret = 0;
fd_set rset;
fd_set wset;
fd_set eset;
if (timeout == NULL) {
/* blocking mode */
return connect(sockfd, addr, addrlen);
}
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
if ((n = connect(sockfd, addr, addrlen)) < 0) {
if (errno != EINPROGRESS) {
return -1;
}
}
if (n == 0) {
goto ok;
}
#ifdef __linux__
retry_again:
#endif
FD_ZERO(&rset);
FD_ZERO(&eset);
FD_SET(sockfd, &rset);
FD_SET(sockfd, &eset);
wset = rset;
if ((n = select(sockfd + 1, &rset, &wset, &eset, timeout)) == 0) {
error = ETIMEDOUT;
} else if ((FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))) {
len = sizeof(error);
/*
BSD-derived systems set errno correctly
Solaris returns -1 from getsockopt in case of error
*/
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
ret = -1;
}
} else {
/* whoops: sockfd has disappeared */
ret = -1;
error = errno;
}
#ifdef __linux__
/* this is a linux specific hack that only works since linux updates
* the timeout struct to reflect the time remaining from the original
* timeout value. One day, we should record the start time and calculate
* the remaining time ourselves for portability */
if (ret == -1 && error == EINPROGRESS) {
error = 0;
goto retry_again;
}
#endif
ok:
fcntl(sockfd, F_SETFL, flags);
if (error) {
errno = error;
ret = -1;
}
return ret;
}
int ftp::getaddresses(const char *host, int socktype, struct sockaddr ***sal ){
struct sockaddr **sap;
int n;
#ifdef HAVE_GETADDRINFO
static int ipv6_borked = -1; /* the way this is used *is* thread safe */
struct addrinfo hints, *res, *sai;
#else
struct hostent *host_info;
struct in_addr in;
#endif
if (host == NULL) {
return 0;
}
#ifdef HAVE_GETADDRINFO
memset(&hints, '\0', sizeof(hints));
hints.ai_family = AF_INET; /* default to regular inet (see below) */
hints.ai_socktype = socktype;
if ((n = getaddrinfo(host, NULL, &hints, &res))) {
printf("getaddresses: getaddrinfo failed: ");
return 0;
} else if (res == NULL) {
printf("getaddresses: getaddrinfo failed (null result pointer)");
return 0;
}
sai = res;
for (n = 1; (sai = sai->;ai_next) != NULL; n++)
;
*sal = (sockaddr**) malloc((n + 1)* sizeof(*sal));
sai = res;
sap = *sal;
do {
*sap = (sockaddr*) malloc(sai->;ai_addrlen);
memcpy(*sap, sai->;ai_addr, sai->;ai_addrlen);
sap++;
} while ((sai = sai->;ai_next) != NULL);
freeaddrinfo(res);
#else
if (!inet_aton(host, &in)) {
/* XXX NOT THREAD SAFE (is safe under win32) */
host_info = gethostbyname(host);
if (host_info == NULL) {
printf("getaddresses: gethostbyname failed");
return 0;
}
in = *((struct in_addr *) host_info->;h_addr);
}
*sal = (sockaddr**) malloc(2 * sizeof(*sal));
sap = *sal;
*sap = (sockaddr*)malloc(sizeof(struct sockaddr_in));
(*sap)->;sa_family = AF_INET;
((struct sockaddr_in *)*sap)->;sin_addr = in;
sap++;
n = 1;
#endif
*sap = NULL;
return n;
}
void ftp::freeaddresses(struct sockaddr **sal)
{
struct sockaddr **sap;
if (sal == NULL)
return;
for (sap = sal; *sap != NULL; sap++)
free(*sap);
free(sal);
}
int ftp::hostconnect(string host, int port ,int socktype, struct timeval *timeout){
int n, repeatto, s;
struct sockaddr **sal, **psal;
struct timeval individual_timeout;
int set_timeout = 0;
int err = 0;
n = getaddresses(host.c_str(), socktype, &sal);
if (n == 0)
return -1;
if (timeout != NULL) {
/* is this a good idea? 5s? */
repeatto = timeout->;tv_sec / n >; 5;
if (repeatto) {
individual_timeout.tv_sec = timeout->;tv_sec / n;
} else {
individual_timeout.tv_sec = timeout->;tv_sec;
}
individual_timeout.tv_usec = timeout->;tv_usec;
} else {
individual_timeout.tv_sec = 0;
individual_timeout.tv_usec = 0;
}
/* Boolean indicating whether to pass a timeout */
set_timeout = individual_timeout.tv_sec + individual_timeout.tv_usec;
psal = sal;
while (*sal != NULL) {
s = socket((*sal)->;sa_family, socktype, 0);
if (s != SOCK_ERR) {
switch ((*sal)->;sa_family) {
case AF_INET:
{
struct sockaddr_in *sa =
(struct sockaddr_in *)*sal;
sa->;sin_family = (*sal)->;sa_family;
sa->;sin_port = htons(port);
if (this->;connect_nonb(s, (struct sockaddr *) sa,
sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR)
goto ok;
}
break;
}
err = errno;
::close (s);
}
sal++;
if (err == TIMEOUT_ERROR_VALUE) {
/* if the first attempt timed out, it's highly likely
* that any subsequent attempts will do so also */
break;
}
}
this->;freeaddresses(psal);
return -1;
ok:
this->;freeaddresses(psal);
return s;
}
复制代码
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2