socket 多次连接失败!!

lccly000 2009-12-20 10:54:18
GGJJDDMM,我现在编写一个程序与PLC进行连接的,想计算从发送到收到返回值的时间,我在线程里面连接PLC的,但是我第一次与第二次连接都正常(每次都是断开连接的),第三次就不能socket了,请大家帮忙,着急啊!!QQ:249087345!!
谢谢了

UINT Thread_ReadPlcSta( LPVOID lpParam )
{
SOCKET CScoket_Lister;
SOCKET_ADDRESS IP_Address;
char *cIpAdress;
ReadPlcInfo *Info = (ReadPlcInfo*) lpParam;
CString sReadPlcValue;
CString sUseEndTime;
bool bReadPlcInfo;

USES_CONVERSION;

// 取得时钟频率
/*LARGE_INTEGER litmp ;
QueryPerformanceFrequency(&litmp);
LARGE_INTEGER start;
QueryPerformanceCounter(&start) ;*/
LARGE_INTEGER litmp ;
QueryPerformanceFrequency(&litmp);

bReadPlcInfo = TRUE;

CScoket_Lister = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if ( CScoket_Lister == INVALID_SOCKET )
{
WSAGetLastError();
return -1;
}

struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(Info->nPlcPort); // ASA standard port
server.sin_addr.s_addr = inet_addr( T2A( Info->sPlcIP));

int i;
i = connect(CScoket_Lister, (sockaddr *)&server, sizeof(sockaddr_in));

if (i<0) // #define SOCKET_ERROR (-1)
{
//printf("connect - error %d\n",WSAGetLastError());
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_RUNSTA,_T("打开PLC失败!"));
closesocket(CScoket_Lister);
WSACleanup();
return 1;
}


fd_set fds;//typedef struct fd_set {
// u_int fd_count; /* how many are SET? */
//SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
//} fd_set;

FD_ZERO(&fds);//#define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)

timeval tv; //struct timeval {
//long tv_sec; /* seconds */
//long tv_usec; /* and microseconds */
//};

tv.tv_sec = 5;
tv.tv_usec = 0;

// wait for permission to send

FD_SET(CScoket_Lister, &fds);//#define FD_SET(fd, set) do { \
// if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \
// ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\
//} while(0)
//此处将s赋给fds,使fds的成员fd_count=1,fd_array[0]=s;

i = select(32, NULL, &fds, NULL, &tv); // write
//多路复用——select()//功能:用来检测一个或多个套接字状态。
//格式:int PASCAL FAR select(int nfds,fd_set FAR * readfds,fd_set FAR * writefds,
//fd_set FAR * exceptfds(//指向要检测是否出错的指针),const struct timeval FAR * timeout);

// build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn

unsigned char obuf[261] = {0};
unsigned char ibuf[261] = {0};
unsigned short unit =1;
unsigned short reg_no = Info->nRegAdress; //数据偏移量
unsigned short num_regs = Info->nReadLen; //读取数量

for (i=0;i<5;i++) obuf[i] = 0;

obuf[5] = 6;//传输标志(2)协议标志(2)后续字节计数(2)
obuf[6] = char(unit);//Unit Identifier(slave address)
obuf[7] = Info->nMBTCPFC;//功能码
obuf[8] = reg_no >> 8;//读寄存器起始地址高八位
obuf[9] = reg_no & 0xff;////读寄存器起始地址低八位
obuf[10] = num_regs >> 8;//读寄存器数量高八位
obuf[11] = num_regs & 0xff;//读寄存器数量低八位
// send request

while ( Info->bThreadReadPlc )
{
sReadPlcValue = "";
i = send(CScoket_Lister, (const char *)obuf, 12, 0);//int PASCAL FAR send (
//IN SOCKET s,
//IN const char FAR * buf,
//IN int len,
//IN int flags);

if (i<12)
{
//printf("failed to send all 12 chars\n");
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_RUNSTA,_T("发送MODBUS格式错误!"));
}
// wait for response

FD_SET(CScoket_Lister, &fds);

i = select(32, &fds, NULL, NULL, &tv); //read

if (i<=0)
{
//printf("no TCP response received\n");
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_RUNSTA,_T("发送错误!"));
closesocket(CScoket_Lister);
WSACleanup();
return 1;
}

// read response

i = recv(CScoket_Lister, ( char*)ibuf, 261, 0);
if (i<9)
{
if (i==0)
{
//printf("unexpected close of connection at remote end\n");
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_RUNSTA,_T("PLC无数据反馈!"));
}
else
{
printf("response was too short - %d chars\n", i);
}
}
else if (ibuf[7] & 0x80)
{
printf("Modbus exception response - type %d\n", ibuf[8]);
}

if ( i != ( 10 + num_regs / 8 ) )
{
printf("Modbus exception response - type %d\n", ibuf[8]);
}
{
if ( Info->nMBTCPFC == 1 )
{
for (i=9;i<= num_regs/8+10;i++)
{
CString sTemp;
int nReadPlcValue_Low = ibuf[i];
int nReadPlcValue_High = ibuf[++i];
int nReadPlcValue = nReadPlcValue_High * 256 + nReadPlcValue_Low;
sTemp.Format(_T("%d"),nReadPlcValue);
sReadPlcValue += sTemp;
if ( sReadPlcValue == Info->sSetPlcValue )
{
Info->bThreadReadPlc = FALSE;
}
if( num_regs > 1 && i<num_regs/8+10 )
{
sReadPlcValue += " ";
}
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_READPLCVALUE,sReadPlcValue);
}
}
}
if( i != ( 9 + 2*num_regs) )
{
printf("Modbus exception response - type %d\n", ibuf[8]);
}
{
if ( Info->nMBTCPFC == 3 )
{
for (i=9;i<= num_regs+9;i++)
{
CString sTemp;
int nReadPlcValue_High = ibuf[i];
int nReadPlcValue_Low = ibuf[++i];
int nReadPlcValue = nReadPlcValue_High * 256 + nReadPlcValue_Low;
sTemp.Format(_T("%d"),nReadPlcValue);
sReadPlcValue += sTemp;
if ( sReadPlcValue == Info->sSetPlcValue )
{
Info->bThreadReadPlc = FALSE;
}
if( num_regs > 1 && i < num_regs + 9 )
{
sReadPlcValue += " ";
}
}
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_READPLCVALUE,sReadPlcValue);
}
}

LARGE_INTEGER whileend;
QueryPerformanceCounter(&whileend) ;
double dTotalTime = (double)(whileend.QuadPart-Info->lstart.QuadPart)
/ (double)litmp.QuadPart; //秒
sUseEndTime.Format(_T("%lf"),dTotalTime);
sUseEndTime += " 秒";
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_USETIME,sUseEndTime);
}

//closesocket(CScoket_Lister);
shutdown(CScoket_Lister,2);
WSACleanup();

LARGE_INTEGER end;
QueryPerformanceCounter(&end) ;
double dTotalTime = (double)(end.QuadPart-Info->lstart.QuadPart)
/ (double)litmp.QuadPart; //秒
sUseEndTime.Format(_T("%lf"),dTotalTime);
sUseEndTime += " 秒";
SetDlgItemText(AfxGetMainWnd()->m_hWnd,IDC_EDIT_USETIME,sUseEndTime);
}
...全文
370 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
rwjlqn 2009-12-23
  • 打赏
  • 举报
回复
把出错信息贴出来
赵4老师 2009-12-21
  • 打赏
  • 举报
回复
可能是服务器端限制同时连接数为2了
大海啊全是水 2009-12-21
  • 打赏
  • 举报
回复
shutdown(CScoket_Lister,2); 并没有关闭socket 如果要关闭socket 必须要使用closesocket函数.
shutdown函数一般用来进行优美关闭,也就是在完全停止发送和接收数据以后再进行关闭.
大海啊全是水 2009-12-21
  • 打赏
  • 举报
回复
连接失败后 查看一下他的 error code (GetLastError 或者 WSAGetLastError)
lccly000 2009-12-20
  • 打赏
  • 举报
回复
自己顶一下自己

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧