socket通信是支持域名发送的,但是不能直接用域名发送,需要先解析域名,获取到实际IP地址才可以。
int SendMsg(char *szMsg, int nMsgLen)
{
int nRet = 0;
if(strlen(m_szIp) <= 0)
return -1;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
return -1;
m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == m_sock)
{
WSACleanup();
return -1;
}
SOCKADDR_IN saddr;
if (NULL == strstr(m_szIp, "com"))
{
saddr.sin_addr.S_un.S_addr = inet_addr(m_szIp);
}
else
{
struct hostent *hptr = NULL;
if (NULL == (hptr = gethostbyname(m_szIp)))
{
return 1;
}
CopyMemory(&saddr.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length);
printf("hptr->h_addr_list[0] = %s\n", hptr->h_addr_list[0]);
}
saddr.sin_family = AF_INET;
saddr.sin_port = htons((WORD)m_port);
// set the socket in non-blocking
unsigned long mode = 1;
int result = ioctlsocket(m_sock, FIONBIO, &mode);
if (result != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", result);
printf("connect start...");
nRet = connect(m_sock, (const sockaddr *)&saddr, sizeof(SOCKADDR_IN));
printf("connect finish...");
// restart the socket mode
mode = 0;
result = ioctlsocket(m_sock, FIONBIO, &mode);
if (result != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", result);
fd_set Write;
FD_ZERO(&Write);
FD_SET(m_sock, &Write);
// check if the socket is ready
TIMEVAL timeval = {0};
timeval.tv_sec = 3;
timeval.tv_usec = 0;
printf("select start...");
int selectresult = select(0, NULL, &Write, NULL, &timeval);
printf("select finish.");
switch (selectresult)
{
case -1:
return R_FAILURE;
case 0 : //超时
return R_FAILURE;
default: //读就绪
break;
}
if(!FD_ISSET(m_sock, &Write))
{
printf("FD_ISSET error.");
return S_FALSE;
}
printf("send start...");
setsockopt(m_sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeval, sizeof(timeval));
nRet = send(m_sock, szMsg, nMsgLen, 0);
printf("send finish.");
return S_OK;
}
int RecvMsg(std::string &srecv, int timeout/*=3*/)
{
struct timeval Timeout;
fd_set rfds;
int nfds, selectresult;
char buff[4097] = {0};
int buffLen = 4096;
int rest = buffLen, done = 0, recvbytes;
int nlen = 0;
//设置超时时间
Timeout.tv_sec = timeout;
Timeout.tv_usec = 0;
#ifndef _MSC_VER
nfds = getdtablesize();
#else
nfds = 0;
#endif
FD_ZERO(&rfds);
FD_SET(m_sock, &rfds);
if(timeout < 0)
selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, NULL);
else
selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, &Timeout);
switch (selectresult)
{
case -1:
return R_FAILURE;
case 0 : //超时
return R_FAILURE;
default: //读就绪
break;
}
while(recvbytes = recv(m_sock, buff, rest, 0))
{
if(recvbytes == -1)
{
return R_FAILURE;
}
if(recvbytes < 0)
{
//接收异常
return R_FAILURE;
}
if(recvbytes ==0)
{
//连接被对端关闭
return (recvbytes);
}
srecv +=buff;
done += recvbytes;
memset(buff,0,4097);
if(recvbytes == 4096)
{
continue;
}
//select again
Timeout.tv_sec = 0;
Timeout.tv_usec = 500000; /* 0.5 sec */
if(timeout < 0)
selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, NULL);
else
selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, &Timeout);
switch (selectresult)
{
case -1:
return done;
case 0 : //超时
return done;
default: //读就绪
break;
}
}
return (done + recvbytes);
}