// testsocketclient.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#include <mstcpip.h>
#pragma comment(lib, "Ws2_32.lib")
SOCKET sockClient = 0;
static int conn_status = 0;
#define IP_ADDRESS ("192.168.207.131")
#define PORT (9099)
#include <iostream>
using namespace std;
int socket_tcp_alive(int socket)
{
int ret = 0;
int keep_alive = 1;
ret = setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&keep_alive, sizeof(keep_alive));
if (ret == SOCKET_ERROR)
{
printf("setsockopt failed: %d \n", WSAGetLastError());
return -1;
}
struct tcp_keepalive in_keep_alive = { 0 };
unsigned long ul_in_len = sizeof(struct tcp_keepalive);
struct tcp_keepalive out_keep_alive = { 0 };
unsigned long ul_out_len = sizeof(struct tcp_keepalive);
unsigned long ul_bytes_return = 0;
in_keep_alive.onoff = 1; /*打开keepalive*/
in_keep_alive.keepaliveinterval = 5000; /*发送keepalive心跳时间间隔-单位为毫秒*/
in_keep_alive.keepalivetime = 1000; /*多长时间没有报文开始发送keepalive心跳包-单位为毫秒*/
ret = WSAIoctl(socket, SIO_KEEPALIVE_VALS, (LPVOID)&in_keep_alive, ul_in_len,
(LPVOID)&out_keep_alive, ul_out_len, &ul_bytes_return, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl failed: %d \n", WSAGetLastError());
return -1;
}
return 0;
}
int tcp_connect_server()
{
int save_errno;
SOCKADDR_IN server_addr;
conn_status = 0;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
server_addr.sin_port = htons(PORT);
sockClient = ::socket(PF_INET, SOCK_STREAM, 0);
if (sockClient == -1)
return sockClient;
conn_status = ::connect(sockClient, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (conn_status == -1)
{
save_errno = errno; //清理
closesocket(sockClient);
errno = save_errno; //the close may be error
return -1;
}
// evutil_make_socket_nonblocking(sockfd);
return sockClient;
}
DWORD WINAPI monitorThread(LPVOID pM)
{
while (1)
{
char szRecvBuf[10] = { 0 };
// send(sockClient, "this is qiang ge1233", strlen("this is qiang ge1234") + 1, 0);
int nRet = recv(sockClient, szRecvBuf, 1, MSG_PEEK); // 注意, 最后一个参数必须是MSG_PEEK, 否则会影响主线程接收信息
if (nRet <= 0)
{
printf("监测到啦: nRet is %d\n", nRet);
closesocket(sockClient);
sockClient = NULL;
sockClient = tcp_connect_server();
if (conn_status != -1)
socket_tcp_alive(sockClient);
// break;
}
Sleep(5000);
}
return 0;
}
void main()
{
//加载套接字库,版本协商
WORD wVersionRequired;
WSADATA wsaData;
int err;
int status, save_errno;
//请求库
//WSAStartup( WORD wVersionRequired, WSADATA lpWSAData );
wVersionRequired = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequired, &wsaData);
if (err != 0)
{
//不等于0就退出
return;
}
//高字节和低字节都不为1
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
WSACleanup();
return;
}
sockClient = socket(AF_INET, SOCK_STREAM, 0);
//设定服务器的地址信息
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr(IP_ADDRESS);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(PORT);
while (1)
{
conn_status = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (conn_status == -1)
{
save_errno = errno; //清理
errno = save_errno; //the close may be error
Sleep(3000);
cout << "one lian test" << endl;
continue;
}
else
{
socket_tcp_alive(sockClient);
break;
}
}
HANDLE handle = CreateThread(NULL, 0, monitorThread, NULL, 0, NULL);
// send(sockClient, "this is qiang ge", strlen("this is qiang ge") + 1, 0);
getchar();
closesocket(sockClient);
WSACleanup();
system("PAUSE");
}