?? tcp.cpp
字號:
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int sd_connect =-1, sd_bind =-1, sd_accept =-1;
int wsa_ok =0;
int tcp_init()
{
WSAData wsa;
sd_bind =sd_connect =sd_accept =-1;
if(WSAStartup(MAKEWORD(1, 1), &wsa) !=0)
return -1;
wsa_ok =1;
return 0;
}
int tcp_exit()
{
if(sd_connect >=0) closesocket(sd_connect);
if(sd_accept >=0) closesocket(sd_accept);
if(sd_bind >=0) closesocket(sd_bind);
if(wsa_ok) WSACleanup();
sd_connect =sd_accept =sd_bind =-1;
return 0;
}
int tcp_status(int sd, char *type, int timeout)
{
fd_set rset, wset, eset;
fd_set FAR *prset =NULL, *pwset =NULL, *peset =NULL;
struct timeval tval;
int i, status, err_no =0;
time_t t1, t2;
MSG msg;
tval.tv_sec =0;
tval.tv_usec =0;
time(&t1);
t2 =t1;
while(t2-t1 < timeout)
{
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
for(i =0; i<(int)strlen(type); i++)
{
if(type[i] =='r') { FD_SET(sd, &rset); prset =&rset; }
if(type[i] =='w') { FD_SET(sd, &wset); pwset =&wset; }
if(type[i] =='e') { FD_SET(sd, &eset); peset =&eset; }
}
status =select(sd+1, prset, pwset, peset, &tval);
time(&t2);
if(status ==0)
{
if(PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if(msg.message ==WM_QUIT) return -1;
}
if(t2-t1 <timeout) continue;
else
{
if(prset) FD_CLR((UINT)sd,&rset);
if(pwset) FD_CLR((UINT)sd,&wset);
if(peset) FD_CLR((UINT)sd,&eset);
SetLastError(WSAETIMEDOUT);
return -10;
}
}
if(peset && FD_ISSET(sd, peset))
{
if(prset !=NULL) FD_CLR((UINT)sd,&rset);
if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
if(peset !=NULL) FD_CLR((UINT)sd,&eset);
err_no =WSAGetLastError();
/*
len =sizeof(errno);
getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
*/
return -1;
}
if((prset && FD_ISSET(sd, prset)) || (pwset && FD_ISSET(sd, pwset)))
{
err_no =WSAGetLastError();
/*
len =sizeof(errno);
getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
*/
}
if(prset !=NULL) FD_CLR((UINT)sd,&rset);
if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
if(peset !=NULL) FD_CLR((UINT)sd,&eset);
if(status <0)
err_no =WSAGetLastError();
if(err_no ==WSAEINTR) return WSAEINTR;
if(err_no)
{
return -1;
}
else break;
}
return 0;
}
int tcp_bind(HWND hWnd, int port)
{
struct sockaddr_in addr;
char temp[200];
int sd;
sd =-1;
if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
{
sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port =htons((unsigned short)port);
int l =1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&l, sizeof(l));
/*setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, (char *)&l, sizeof(l));*/
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) <0)
{
sprintf(temp, "bind failed! errno:%d", WSAGetLastError());
closesocket(sd);
return -1;
}
if(hWnd && WSAAsyncSelect(sd, hWnd, WM_APP+100, FD_READ|FD_ACCEPT) !=0)
{
sprintf(temp, "tcp_bind:WSAAsyncSelect failed!");
closesocket(sd);
return -2;
}
sd_bind =sd;
listen(sd_bind, 5);
return sd;
}
int tcp_accept(int sd, int timeout)
{
int sd_acc =-1;
struct sockaddr_in sa;
int len;
/*unsigned long l;*/
if(tcp_status(sd, "rw", timeout) <0)
return -1;
len =sizeof(sa);
if((sd_acc =accept(sd, (struct sockaddr *)&sa, &len)) <0)
return -1;
sd_accept =sd_acc;
/* l =1;
if(ioctlsocket(sd_acc, FIONBIO, &l) <0)
{
closesocket(sd);
return -1;
}*/
return sd_acc;
}
int tcp_connect(char *hostname, int port, int timeout)
{
struct hostent *hp;
struct sockaddr_in addr;
char temp[200];
unsigned long ul;
long l;
int sd =-1;
sd =-1;
if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
{
sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
return -1;
}
memset(&addr, 0, sizeof(addr));
ul =inet_addr(hostname);
if(ul ==0xffffffff)
{
if((hp =gethostbyname(hostname)) ==NULL)
{
sprintf(temp, "gethostbyname and inet_addr failed! errno:%d", WSAGetLastError());
closesocket(sd);
return -1;
}
memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
}
else addr.sin_addr.s_addr=ul;
addr.sin_family =AF_INET;
addr.sin_port =htons((unsigned short)port);
l =1;
/*if(ioctlsocket(sd, FIONBIO, (unsigned long *)&l) <0)
{
closesocket(sd);
return -1;
}*/
if(setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&l, sizeof(l)) <0)
{
closesocket(sd);
return -1;
}
while(connect(sd, (struct sockaddr *)&addr, sizeof(addr)) !=0)
{
int err_no =WSAGetLastError();
if(err_no ==WSAEINTR) continue;
if(err_no ==WSAEINPROGRESS) break;
sprintf(temp, "connect:連接服務器失敗!\n檢查服務器端程序是否運行\n且主機地址是否%s, 端口是否%d\n errno=%d",
hostname, port, err_no);
closesocket(sd);
return -1;
}
if(tcp_status(sd, "w", timeout) <0)
{
sprintf(temp, "status:連接服務器失敗!\n檢查服務器端程序是否運行\n且主機地址是否%s, 端口是否%d\n"
"errno=%d",
hostname, port, WSAGetLastError());
closesocket(sd);
return -1;
}
sd_connect =sd;
return sd;
}
void tcp_disconnect(int sd)
{
if(sd >0)
{
closesocket(sd);
if(sd ==sd_connect) sd_connect =-1;
if(sd ==sd_accept) sd_accept =-1;
if(sd ==sd_bind) sd_bind =-1;
}
}
void tcp_close(int sd)
{
tcp_disconnect(sd);
}
int tcp_send(int sd, char *buf, int len, int timeout)
{
int len1, len_send =0;
time_t t1, t2;
len_send =0;
time(&t1);
t2 =t1;
while(len_send <len)
{
if(t2-t1 >timeout)
return len_send;
if(tcp_status(sd, "w", timeout-(t2-t1)) <0)
return len_send;
if((len1 =send(sd, &buf[len_send], len-len_send, 0)) <=0)
{
/*if(GetLastError() ==WSAEWOULDBLOCK)
{
time(&t2);
continue;
}*/
return len_send;
}
len_send +=len1;
time(&t2);
}
return len_send;
}
int tcp_recv(int sd, char *buf, int len, int timeout)
{
int len1, len_recv;
time_t t2, t1;
len_recv =0;
time(&t1);
t2 =t1;
while(len_recv <len)
{
if(t2 -t1 >timeout)
return len_recv;
if(tcp_status(sd, "r", timeout-(t2-t1)) <0)
return len_recv;
if((len1 =recv(sd, &buf[len_recv], len-len_recv, 0)) <=0)
{
/*if(timeout ==0) break;
if(GetLastError() ==WSAEWOULDBLOCK)
{
time(&t2);
continue;
}*/
return len_recv;
}
len_recv +=len1;
time(&t2);
}
return len_recv;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -