我正在开发一个应该从norma 5000记录数据的程序,但它的接口就像normas tcpconnection在一个仲裁时间(0.2-6h)之后随机关闭,但我需要记录更长的时间。
当它关闭连接时,我可以重新启动程序,它将继续记录。所以我想到了在tcpconnection中断时重启我的套接字。但我每次都重新开始工作..我想你想看的功能是shutdownCon,init和main。
我的问题是:我做错了什么?
当pcp Connection停止工作10053(WSAECONNABORTED)或10054(WSAECONNRESET)时,我得到winsock错误。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
#pragma comment(lib, "Ws2_32.lib")
#define WIN 1
#define debug 1
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
#define HOST "192.168.0.101"
#define PORT 23
#define SOCKET_HANDLE_FMT_PFX ""
#define SOCKET_HANDLE_FMT "u" /* "%u" - 'typedef u_int SOCKET' */
typedef SOCKET socket_handle_t;
typedef struct {
socket_handle_t h;
} *socket_t;
/****************************************************************************
**/
static void Delay(double seconds)
{
Sleep((DWORD)(seconds * 1000));
}
/****************************************************************************
**/
void wsa_error(char *func,int error)
{
fprintf(stderr,"%s() failed, error %d\n",
func,error == -1 ? WSAGetLastError() : error);
int c; /* must be int to hold EOF */
while((c = getchar()) != '\n' && c != EOF);
}
/****************************************************************************
**/
int socket_setup(void)
{
#if WIN
WSADATA wsaData;
int wsaerrno;
/*
* Initialize Windows Socket DLL
*/
if ( (wsaerrno = WSAStartup(
MAKEWORD(1,1), /* at least version 1.1 */
&wsaData)) != 0 )
{
wsa_error("WSAStartup",wsaerrno);
return -1;
}
#endif /* WIN */
return 0; /* OK */
}
/****************************************************************************
**/
int socket_cleanup(void)
{
#if WIN
if ( WSACleanup() == SOCKET_ERROR )
wsa_error("WSACleanup",-1);
#endif
return 0; /* OK */
}
/****************************************************************************
**/
socket_t socket_create(void)
{
socket_handle_t sh;
socket_t s;
sh = socket(AF_INET,SOCK_STREAM,0);
#if WIN
if ( sh == INVALID_SOCKET )
{
wsa_error("socket",-1);
return NULL;
}
#endif
s = calloc(1,sizeof(*s));
if ( !s )
return NULL;
s->h = sh;
return s; /* OK */
}
/****************************************************************************
**/
int socket_connect(socket_t s,struct sockaddr *addr,int addrlen)
{
int ret = 0; /* OK */
#if WIN
if ( connect(s->h,addr,addrlen) == SOCKET_ERROR )
{
wsa_error("connect",-1);
return -1;
}
#endif
return 0; /* OK */
}
/****************************************************************************
**/
int socket_recv(socket_t s,void *buf,int len,int flags)
{
register int l;
#if WIN
l = recv(s->h,buf,len,flags);
if ( l == SOCKET_ERROR )
{
wsa_error("recv",-1);
return -1;
}
#endif
return l;
}
/****************************************************************************
**/
int socket_send(socket_t s,void *buf,int len,int flags)
{
register int slen; /* sent length */
#if WIN
slen = send(s->h,buf,len,flags);
if ( slen == SOCKET_ERROR )
{
wsa_error("send",-1);
return -1;
}
#endif
return slen;
}
/****************************************************************************
**/
int socket_puts(socket_t s,char *str)
{
char buf[1024];
strcpy(buf,str);
strcat(buf,"\n");
if ( socket_send(s,buf,strlen(buf),0) < 0 )
return -1;
return 0;
}
/****************************************************************************
**/
int socket_gets(socket_t s,char *str)
{
char buf[1024];
char *p;
if ( socket_recv(s,buf,sizeof(buf),0) < 0 )
return -1;
if ( (p = memchr(buf,'\n',sizeof(buf))) != NULL )
{
if ( p > buf && p[-1] == '\r' )
p--;
*p = '\0';
}
else
buf[sizeof(buf)-1] = '\0';
strcpy(str,buf);
return strlen(str);
}
/****************************************************************************
**/
/*is some thing wrong here?*/
int shutdownCon(socket_t s){
char buff[1024];
if (shutdown(s->h,2)== SOCKET_ERROR)
{
wsa_error("shutdownCon",-1);
return -1;
}
while(socket_gets(s,buff)> 1);
if(closesocket(s->h) == SOCKET_ERROR)
{
wsa_error("shutdownCon",-1);
return -1;
}
socket_cleanup();
return 0;
}
/*is some thing wrong here?*/
int init(socket_t *s){
struct sockaddr_in saddr;
struct sockaddr_in *addr_in = (struct sockaddr_in *)&saddr;
/* socket (TCP/IP) API initialization: */
if ( socket_setup() < 0 )
return -1;
/*
* Connect to the instrument:
*/
/* set destination IP address and TCP port: */
memset(addr_in,0,sizeof(struct sockaddr_in));
addr_in->sin_family = AF_INET;
addr_in->sin_port = htons(PORT);
addr_in->sin_addr.s_addr = inet_addr(HOST);
/* create socket: */
*s = socket_create();
if ( !*s )
return -1;
#if debug
fprintf(stderr,"socket_connect() ...\n");
#endif
if ( socket_connect(*s,(struct sockaddr *)&saddr,sizeof(saddr)) < 0 )
return 1;
#if debug
fprintf(stderr,"socket_connect(): done\n");
#endif
return 1;
}
int recon(socket_t *s){
shutdownCon(*s);
init(s);
return 0;
}
void printTime(){
struct _timeb timebuffer;
char *timeline;
_ftime( &timebuffer );
timeline = ctime( & ( timebuffer.time ) );
printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] );
}
int main(int argc,char *argv[])
{
socket_t s;
char buffer[1024];
char oper[1024];
init(&s);
#if debug
fprintf(stderr,"trying to get id from norma \n");
if ( socket_puts(s,"*IDN?") < 0 )
return 1;
if ( socket_gets(s,buffer) < 0 )
return 1;
puts(buffer);
#endif
//##################CONF FROM FLUKE#####################
/* Bring the instrument into a default state: */
//socket_puts(s,"*RST");
/* Select three wattmeter configuration: */
//socket_puts(s,"ROUT:SYST \"3W\"");
/* SYNC source = voltage phase 1: */
//socket_puts(s,"SYNC:SOUR VOLT1");
/* Set voltage range on voltage channel 1 to 300 V: */
//socket_puts(s,"VOLT1:RANG 300.0");
/* Set current channel 1 to autorange: */
//socket_puts(s,"CURR1:RANG:AUTO ON");
/* Set averaging time to 1 second: */
//socket_puts(s,"APER 1.0");
/* Select U, I, P measurement: */
//socket_puts(s,"FUNC \"VOLT1\",\"CURR1\",\"POW1:ACT\"");
/* Run continuous measurements: */
//socket_puts(s,"INIT:CONT ON");
//######################################################
socket_puts(s,"SYST:KLOC REM");
socket_puts(s,"*RST");
socket_puts(s,"ROUT:SYST \"3w\"");
socket_puts(s,"APER 0.025");
socket_puts(s,"INP1:COUP DC");
socket_puts(s,"FUNC \"VOLT1\",\"CURR1\",\"POW1\",\"POW1:APP\",\"POW1:ACT\",\"PHASE1\"");
socket_puts(s,"INIT:CONT ON");
Delay(5.0); /* Wait 2 seconds */
int opstat = -1;
while(1){
//if(opstat != -1)
// recon(&s);
opstat = 0;
while((opstat & 0x400) == 0){
if(socket_puts(s,"STAT:OPER:EVEN?")==-1){
recon(&s);
continue;
}
memset(oper,0,sizeof(oper));
if(socket_gets(s,oper) == -1){
recon(&s);
continue;
}
opstat = atoi(oper);
}
if(socket_puts(s,"DATA?") == -1){/* Query the measurement */
recon(&s);
continue;
}
memset(buffer,0,sizeof(buffer)); /* Clear buffer */
if(socket_gets(s,buffer) == -1){/* read values */
recon(&s);
continue;
}
puts(buffer); /* Print the value on the screen */
//Delay(1.0); /* Wait 2 seconds */
printTime();
}
return 0;
}
/****************************************************************************
**/
最好的问候baot
答案 0 :(得分:0)
当对其中一个WinSock2函数的调用失败时,“shutdownCon”函数不应该提前返回。因此,例如,如果对“shutdown”的调用失败,“shutdownCon”将报告错误,然后退出而不调用“closesocket”或“socket_cleanup”。因此,当“shutdownCon”失败时,它可以使socket和WinSock2库处于不同的状态(使您的程序难以可靠地继续,因为它不知道其中的状态)。
如果我是你,我还会分离WinSock2库的初始化和套接字的初始化。我会在你的程序开始时初始化一次WinSock2库,而不是清理它。换句话说,从“init”调用“socket_setup”并将其置于“main”(当然在调用“init”之前),然后从“shutdownCon”调用“socket_cleanup”。 / p>
如果以上都不起作用,您可以尝试在关闭套接字和初始化新套接字之间插入延迟。如果这没有帮助,程序可能需要开始检查WinSock2库返回的错误值,并根据错误的不同做不同的事情。
答案 1 :(得分:-1)
创建套接字后,可以设置某些选项。
其中一个选项是SO_KEEPALIVE套接字选项。
设置选项会导致套接字保持打开状态而不是自动关闭。
可以使用以下内容设置keepalive选项:
int keepAlive = 1;
result = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
&keepAlive, (socklen_t)sizeof(keepAlive));