Socket實現非阻塞連線

2021-04-25 00:57:55 字數 3333 閱讀 9860

#include

#include

#include

#include

#pragma comment(lib, "ws2_32.lib")

#define time_out_time 20  //connect超時時間20秒

void geturl(char *url)

; socket sockfd;

struct sockaddr_in addr;

struct hostent *purl;

char myurl[bufsiz];

char *phost = 0, *pget = 0;

char host[bufsiz], get[bufsiz];

char header[bufsiz] = "";

static char text[bufsiz];

int i;

int timeout;

int error=-1, len;

len = sizeof(int);

int ret;

timeval tm;

fd_set set;

/* * windows下使用socket必須用wsastartup初始化,否則不能呼叫

*/ if(wsastartup(makeword(2,2), &wsadata))

/* * 分離url中的主機位址和相對路徑

*/ strcpy(myurl, url);

for (phost = myurl; *phost != '/' && *phost != '/0'; ++phost);

if ( (int)(phost - myurl) == strlen(myurl) )

strcpy(get, "/");

else

strcpy(get, phost);

*phost = '/0';

strcpy(host, myurl);

printf("%s/n%s/n", host, get);

/* * 設定socket引數,並未真正初始化

*/ sockfd = socket(pf_inet, sock_stream, ipproto_tcp);

if (sockfd == invalid_socket)

timeout = 6000; //設定傳送超時6秒

if (setsockopt(sockfd, sol_socket, so_sndtimeo, (char*)&timeout, sizeof(timeout)) == socket_error)

timeout = 6000; //設定接收超時6秒

if (setsockopt(sockfd, sol_socket, so_rcvtimeo, (char*)&timeout, sizeof(timeout)) == socket_error)

//設定非阻塞連線

unsigned long ul = 1;

ret = ioctlsocket(sockfd, fionbio, (unsigned long*)&ul);

if (ret == socket_error)

purl = gethostbyname(host);

addr.sin_family = af_inet;

addr.sin_addr.s_addr = *((unsigned long*)purl->h_addr);

addr.sin_port = htons(80);

/* * 組織傳送到web伺服器的資訊

* 為何要傳送下面的資訊請參考http協議的約定

/* * 連線到伺服器,傳送請求header,並接受反饋(即網頁源**)

*/ connect(sockfd,(sockaddr *)&addr,sizeof(addr));

//printf("%d", wsagetlasterror());

//select 模型,即設定超時

struct timeval timeout ;

fd_set r;

fd_zero(&r);

fd_set(sockfd, &r);

timeout.tv_sec = 15; //連線超時15秒

timeout.tv_usec =0;

ret = select(0, 0, &r, 0, &timeout);

if ( ret <= 0 )

send(sockfd, header, strlen(header), 0);

//sleep(5000);

while ( (recv(sockfd, text, bufsiz, 0) > 0) || (wsagetlasterror() == wsaewouldblock))

printf("%s", "完成!/n");

closesocket(sockfd);

wsacleanup();

} int main()

return 0;

}以上這段**中,有乙個geturl函式,該函式的作用是傳送並接收資料報。

在該函式進行了socket超時連線設定,所以在connect時會返回wsaewouldblock(10035)錯誤,若在recv時不加上wsaewouldblock判斷,就接收不到資料。

備註:以下**http://www.moon-soft.com/doc/6652.htm

把csdn與中文yahoo翻了底朝天,也沒找到如何設定socket的連線超時的滿意方法,問此問題的兄弟已有一大堆,這裡偶就講一下win下如何設定socket的connect超時。

設 置connect的超時很簡單,csdn上也有人提到過使用select,但卻沒有乙個令人滿意與完整的答案。偶所講的也正是select函式,此函式集 成在winsock1.1中,簡單點講,"作用使那些想避免在套接字呼叫過程中被鎖定的應用程式,採取一種有序的方式,同時對多個套接字進行管理" (《windows網路程式設計技術》原話)。使用方法與解釋請見《windows網路程式設計技術》。

在使用此函式前,需先將socket設定為非鎖定模式,這樣,在connect時,才會立馬跳過,同時,通常也會產生乙個wsaewouldblock錯誤,這個錯誤沒關係。再執行select則是真正的超時。

非阻塞socket 的連線

方案1 int connect socket timeout int sockfd,char dest host,int port,int timeout else memcpy address.sin addr,host h addr list 0 sizeof address.sin addr ...

socket阻塞與非阻塞

何為阻塞?在以上過程中若連線還沒到來,那麼接受阻塞,程式執行到這裡不得不掛起,cpu轉而執行其他執行緒。在以上過程中若資料還沒準備好,請閱讀會一樣也會阻塞。阻塞式網路io的特點 多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且占用一些cpu時間。每個執行緒遇到外部為準備好的時候,都會阻塞掉。阻塞...

轉阻塞socket和非阻塞socket

讀操作 對於阻塞的socket,當socket的接收緩衝區中沒有資料時,read呼叫會一直阻塞住,直到有資料到來才返 回。當socket緩衝區中的資料量小於期望讀取的資料量時,返回實際讀取的位元組數。當sockt的接收緩衝 區中的資料大於期望讀取的位元組數時,讀取期望讀取的位元組數,返回實際讀取的長...