首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

100分,SOCKET重新连接的有关问题

2012-06-15 
100分求助,SOCKET重新连接的问题下面的代码是连接SOCKET服务器的代码,如何判断SOCKET是否断开?如果断开后

100分求助,SOCKET重新连接的问题
下面的代码是连接SOCKET服务器的代码,如何判断SOCKET是否断开?如果断开后自动重连的代码改如何写呢?

----------------------
string socket_ip = "127.0.0.1";

int socket_port = 19001;

if (err)
{
printf("客户端的嵌套字打开失败!\n");
return 0;//结束
}

SOCKET clientSocket=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN clientsock_in;
clientsock_in.sin_addr.S_un.S_addr=inet_addr(socket_ip.c_str());
clientsock_in.sin_family=AF_INET;
clientsock_in.sin_port=htons(socket_port);
//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数
//listen(clientSocket,5);
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));//开始连接

------------------

多谢?

[解决办法]
//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数

你别口口声声喊着第三个参数,结果给一个错的第三个参数,你运气好IPV4的addr和SOCKADDR长度一样,碰到IPV6你还传这个SOCKADDR,你就等死吧。

bind(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR_IN));
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR_IN));//开始连接
[解决办法]
楼上说的对。
-
如果连接断开,那么在recv或者send的时候就会失败,window的话可以调用WSAGetLastError(),查看错误代码。linux用errno。

[解决办法]
CMySock::BindSock()
{
sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(4444);

int opt = 1;
int ret = setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, 
(const char*)&opt, sizeof(opt));
if (ret == SOCKET_ERROR)
return -1;

ret=bind(m_sock,(sockaddr *)&servaddr,sizeof(servaddr));
if (ret == SOCKET_ERROR)
int err = WSAGetLastError();

return 0;
}

[解决办法]
WSAGetLastError()
[解决办法]

探讨

引用:

//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数

你别口口声声喊着第三个参数,结果给一个错的第三个参数,你运气好IPV4的addr和SOCKADDR长度一样,碰到IPV6你还传这个SOCKADDR,你就等死吧。

bind(clientSoc……

[解决办法]
不是啊,客户端不需要bind,直接connect就行了。
[解决办法]
用send发送心跳包。

探讨

引用:

不是啊,客户端不需要bind,直接connect就行了。


是这样的,上面一段代码是我连接服务器的逻辑,在连接之后我会进行一些操作,如果在操作的时候如何判断socket是否还在连接状态?如果发现断掉了,就重新连接呢?

[解决办法]
服务端无法修改么?
如果是这样,我只能提供一个思路。
在另外的线程或者进程去检查这个socket是否可写。
可以参考select
或者还有其他的检测手段。
-
最好的办法是服务端也做修改。
客户端长时间的阻塞也不是很好。
虽然阻塞模式会让编码变的简单,但是扩展性会差很多。
如果本来就要实现很简单的功能,阻塞模式也是相当好的。
关键看需要用来解决什么问题。

探讨

引用:

如果处理数据会消耗时间很长(5min以上我觉得就比较长了,这个时间看需要更改)。
那么就可以考虑使用多线程,或者多进程,用另外的进程或线程处理数据。
如果再处理数据中,那么程序就无法保证一定连接。
或者另起线程或进程保证连接。
-
重连接的话最简单的方法:关闭现有的socket。重新建立socket。
引用:

引用 10 楼……

[解决办法]
C/C++ code
BOOL CTcpip::Tcp_ClientOpenInet(unsigned long ip, unsigned short port){    struct sockaddr_in server;    int rval;     unsigned long argp = 1;     struct timeval tv;    char errmsg[255];    fd_set fd;    fd_set readfd;    time_t t1, t2 ;    unsigned char * p;    memcpy(&(server.sin_addr), &ip, sizeof(server.sin_addr));    server.sin_port = htons(port);    server.sin_family = AF_INET;    clisock = socket(AF_INET, SOCK_STREAM, 0);    if (clisock < 0)    {        /* sockid == -1 */        sprintf(errmsg, "Client: socket() create. with error %d",            WSAGetLastError());        DebugLog(errmsg);        return FALSE;    }    ioctlsocket(clisock, FIONBIO, &argp);    FD_ZERO(&fd);     FD_ZERO(&readfd);     time(&t1) ;    t2 = t1 + 5 ;    while (WaitForSingleObject(gReadDataEvent, 30) != WAIT_OBJECT_0)    {        rval = connect(clisock, (struct sockaddr *) &server, sizeof(server)) ;         if (rval != 0)         {            FD_SET(clisock, &fd);            tv.tv_sec = 0;  //gwcfg.timeout;            tv.tv_usec =5000L; //500000L;                        FD_SET(clisock, &readfd);            tv.tv_sec = 0;              tv.tv_usec = 5000L;                    if ((rval = select(0, &readfd,  &fd, NULL, &tv)) <= 0)            {                if (rval == SOCKET_ERROR)                {                    int Error = WSAGetLastError();                    switch(Error)                    {                    case WSANOTINITIALISED:                                                    break;                    case WSAEFAULT: //currently ignore this condition                        TRACE(_T("WARNING: MAX. Message Size exceeded\n"));                        break;                    case WSAENETDOWN:                                                break;                                        default:                        {                            TCHAR buffer[512];                            wsprintf(buffer, _T("SendTo() returned %d"), Error);                                                    }                        break;                    }                }                time(&t1) ;                if (t1 > t2)                {                    /* time out */                    closesocket(clisock);                    p = (unsigned char *) &ip;                                    return FALSE ;                }             }            else            {                argp = 0;   // none block                if (!AsyncMode)                    ioctlsocket(clisock, FIONBIO, &argp);                            return TRUE;            }        }        else        {            argp = 0;   // none block            if (!AsyncMode)                ioctlsocket(clisock, FIONBIO, &argp);                    return TRUE;        }    }    return FALSE; #endif} 

热点排行