当前位置: 技术问答>linux和unix
一个简单TCP通信稳定性的问题
来源: 互联网 发布时间:2016-09-20
本文导语: 下面的代码是一个TCP通信的客户端代码,服务端发送LINUX的指令,例如,ls等,客户端执行相应的指令,并将屏幕输出的结果返回给服务端,出现的问题有: (1)setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));...
下面的代码是一个TCP通信的客户端代码,服务端发送LINUX的指令,例如,ls等,客户端执行相应的指令,并将屏幕输出的结果返回给服务端,出现的问题有:
(1)setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));已经加过这个选项了,但还是偶尔会出现bind的时候有address already in use的情况;
(2)server端有时候因为异常退出,client端也跟着退出,此时重新运行client程序,有时候就会出现上面描述的情况;
此client代码运行于Cent OS 5.2环境,server代码运行于XP,VC6.0
谢谢各位的指教,不甚感激!
代码如下:
/*
* Edition: Original
* Author: sscao
* Created: 2009/04/15
* Modified:
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LISTEN_NUM 100
#define MYPORT 12345
#define MAXLENGTH 1024
typedef struct SrvRetBuf
{
int ret;
char outbuf[MAXLENGTH];
}SrvRetBuf;
int InitSocket(struct sockaddr_in *pMyAddr)
{
int SockFd;
struct sockaddr_in MyAddr;
int ret;
SockFd = socket(AF_INET, SOCK_STREAM, 0);
if (SockFd == -1)
{
perror("socket");
exit(1);
}
MyAddr.sin_family = AF_INET;
MyAddr.sin_port = htons(MYPORT);
MyAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(MyAddr.sin_zero), 0);
int keepIdle = 60;// 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5;// 探测时发包的时间间隔为5 秒
int keepCount = 3;// 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
int flag = 1;
ret = setsockopt(SockFd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof (flag));
if (-1 == ret)
{
perror("setsockopt SO_KEEPALIVE");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
flag = 1;
ret = setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));
if (-1 == ret)
{
perror("setsockopt SO_REUSEADDR");
close(SockFd);
return ret;
}
ret = bind(SockFd, (struct sockaddr*)&MyAddr, sizeof(struct sockaddr));
if (ret == -1)
{
perror("bind");
exit(1);
}
*pMyAddr = MyAddr;
return SockFd;
}
int ServeThread(int *pSockFd)
{
int NewFd = *pSockFd;
int RetryTimes = 0;
int ret;
int readlen = MAXLENGTH;
FILE *pfTmp;
SrvRetBuf BufSend;
char pBufRecv[MAXLENGTH];
int count = 0;
while (1)
{
count = 0;
readlen = MAXLENGTH - 4;
memset(&BufSend, 0, sizeof(BufSend));
memset(pBufRecv, 0, MAXLENGTH);
ret = recv(NewFd, pBufRecv, MAXLENGTH, 0);
if (ret
(1)setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));已经加过这个选项了,但还是偶尔会出现bind的时候有address already in use的情况;
(2)server端有时候因为异常退出,client端也跟着退出,此时重新运行client程序,有时候就会出现上面描述的情况;
此client代码运行于Cent OS 5.2环境,server代码运行于XP,VC6.0
谢谢各位的指教,不甚感激!
代码如下:
/*
* Edition: Original
* Author: sscao
* Created: 2009/04/15
* Modified:
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LISTEN_NUM 100
#define MYPORT 12345
#define MAXLENGTH 1024
typedef struct SrvRetBuf
{
int ret;
char outbuf[MAXLENGTH];
}SrvRetBuf;
int InitSocket(struct sockaddr_in *pMyAddr)
{
int SockFd;
struct sockaddr_in MyAddr;
int ret;
SockFd = socket(AF_INET, SOCK_STREAM, 0);
if (SockFd == -1)
{
perror("socket");
exit(1);
}
MyAddr.sin_family = AF_INET;
MyAddr.sin_port = htons(MYPORT);
MyAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(MyAddr.sin_zero), 0);
int keepIdle = 60;// 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5;// 探测时发包的时间间隔为5 秒
int keepCount = 3;// 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
int flag = 1;
ret = setsockopt(SockFd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof (flag));
if (-1 == ret)
{
perror("setsockopt SO_KEEPALIVE");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
ret = setsockopt(SockFd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
if (-1 == ret)
{
perror("setsockopt SOL_TCP");
close(SockFd);
return ret;
}
flag = 1;
ret = setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (flag));
if (-1 == ret)
{
perror("setsockopt SO_REUSEADDR");
close(SockFd);
return ret;
}
ret = bind(SockFd, (struct sockaddr*)&MyAddr, sizeof(struct sockaddr));
if (ret == -1)
{
perror("bind");
exit(1);
}
*pMyAddr = MyAddr;
return SockFd;
}
int ServeThread(int *pSockFd)
{
int NewFd = *pSockFd;
int RetryTimes = 0;
int ret;
int readlen = MAXLENGTH;
FILE *pfTmp;
SrvRetBuf BufSend;
char pBufRecv[MAXLENGTH];
int count = 0;
while (1)
{
count = 0;
readlen = MAXLENGTH - 4;
memset(&BufSend, 0, sizeof(BufSend));
memset(pBufRecv, 0, MAXLENGTH);
ret = recv(NewFd, pBufRecv, MAXLENGTH, 0);
if (ret
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。