Socket connet的一些疑问

yikesong321 2013-11-04 08:03:14
基于TCP协议, client链接server。
client程序如下:

........
result = connect(vars->clientsocketfd,(struct sockaddr *)&vars->client,sizeof(struct sockaddr));
if( result == 0 )
return true;
else if(result == -1)
{
timeval tm ;
fd_set set ;
int len = sizeof(int) ;
int error = -1 ;
tm.tv_sec = 0 ;
tm.tv_usec = timeout*1000 ;

FD_ZERO( &set ) ;
FD_SET(vars->clientsocketfd, &set);
if( select((int)vars->clientsocketfd + 1 , NULL, &set, NULL, &tm) > 0)
{
if ( getsockopt(vars->clientsocketfd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) ==0 )
if(error == 0)
return true;
}
}
......


Server 代码

.....
if( listen(vars->serversocketfd,1) == -1)
return false;
struct sockaddr_in clientaddr ;
socklen_t len = sizeof(clientaddr) ;
char buffer[20] ;
vars->clientsocketfd = accept(vars->serversocketfd,(struct sockaddr*)&clientaddr,&len) ;
if( vars->clientsocketfd != INVALID_SOCKET )
{
...........
return true;
}
......



当client第一次连接上 server,此时可以正常通信。
但是当client端关闭socket,再次链接server端,
为什么client端还是显示连接成功?
而且都是每次走 result == -1,error== 0这个逻辑。

请问为什么会出现这个问题?








...全文
195 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yikesong321 2013-11-05
  • 打赏
  • 举报
回复
Client端所有代码


Bool SocketManager::openAsClient(String hostName,Int portNumber,TransferMode protocol,UInt timeout)
{
		Log log(moduleName(), "SocketManager openAsClient");
		int nRecvBuf=128*1024;//设置为128kb
		int nSendBuf=128*1024;//设置为128Kb

		if(! (json::isIP(hostName)))
			return false;
		if(portNumber  <= 1024)
			return false;
		vars->asServer = 0;
		vars->asClient = 1;

		// Close Socket
		closeSocket();


		vars->hostName     =   hostName    ;
		vars->portNumber   =   portNumber  ;
		vars->transferMode =   protocol    ;
		vars->timeOut      =   timeout     ;


		// Create Socket
		if(protocol == TM_UDP)
			vars->clientsocketfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
		else if(protocol == TM_TCP )
			vars->clientsocketfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
		else
		{
			log.error("Protocol Not Support");
			return FALSE;
		}

		if(vars->clientsocketfd < 0)
		{
			log.error((String)" open socket fail " + vars->clientsocketfd);
			return FALSE;
		}
		//Set recvBuf  cache
		setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
		//set sendBuf  cache
		setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

		// Set FD   non   Blocking
		if (fcntl(vars->clientsocketfd, F_SETFL, O_NONBLOCK) == -1)
		{
				log.error("Set Client non blocking mode failed");
				return FALSE;
		}


		//convert IP  to Net  Byte Order
		utility::memorySet(0,&vars->client,sizeof(struct sockaddr_in));
		vars->client.sin_family =             AF_INET ;
		vars->client.sin_port   =   htons(portNumber) ;
		if(inet_pton(AF_INET,(const char*)hostName.dataA(),&vars->client.sin_addr) != 1)
			    log.error("Transfer  IP  To  net byte  Fail.");

		//Connect to Server
				int result = 0;
				result     = connect(vars->clientsocketfd,(struct sockaddr *)&vars->client,sizeof(vars->client)) ;
				if( result == 0)
						return true;
				else if((errno == EINPROGRESS))
				{
						timeval    tm  ;
						fd_set     set ;
						Int  len   = sizeof(int) ;
						int  socketERROR =           -1 ;
						tm.tv_sec  =            0 ;
						tm.tv_usec = timeout*1000 ; //超时时间

						FD_ZERO( &set ) ;
						FD_SET(vars->clientsocketfd, &set);
						if( select((int)vars->clientsocketfd + 1 , NULL, &set, NULL, &tm) > 0)
						{
							if(FD_ISSET(vars->clientsocketfd,&set))
							{
								if(getsockopt(vars->clientsocketfd, SOL_SOCKET, SO_ERROR, (void *)&socketERROR, (socklen_t *)&len) == 0)
								{
										if(socketERROR == 0)
										{
												log.error((String)" Connect Server successful  Result :  " + result);
												return true;
										}
								}
							}
						}
				}

				log.error("Time out , connect Server Fail.");
				return FALSE;
}






yikesong321 2013-11-05
  • 打赏
  • 举报
回复
你是说这里绑定的?? // binder Server Address

  utility::memorySet(0,&vars->server,sizeof(struct sockaddr_in));
                vars->server.sin_family      =  AF_INET;
                vars->server.sin_port        =  htons(portNumber);//转接成网络字节函数
                vars->server.sin_addr.s_addr =  htonl(INADDR_ANY);//开放所有网卡地址
 
                if(bind(vars->serversocketfd,(struct sockaddr *)&vars->server,sizeof(vars->server)) == -1)
                {
                    log.error(" BINDER SERVER FAIL");
                    return  false;
                }

yikesong321 2013-11-05
  • 打赏
  • 举报
回复
server端。在socket的时候绑定了端口。 Server端的全部代码:

Bool SocketManager::openAsServer(Int portNumber,TransferMode protocol,UInt timeout)
{
		Log log(moduleName(), "SocketManager openAsServer");
		int nRecvBuf=128*1024;//设置为128kb
		int nSendBuf=128*1024;//设置为128Kb
		if((vars->portNumber != portNumber) || (vars->transferMode != protocol) || (vars->serversocketfd < 0))
		{
				if(portNumber  <= 1024)
				{
					log.error("portNumber Must bigger than 1024");
					return false;
				}

				// Close Socket
				closeSocket();

				vars->asClient    =    0;
				vars->asServer    =    1;

				vars->portNumber   = portNumber;
				vars->transferMode =   protocol;
				vars->timeOut      =    timeout;



				if(protocol == TM_UDP)
						vars->serversocketfd = socket(AF_INET,SOCK_DGRAM,0);
				else if(protocol == TM_TCP )
						vars->serversocketfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
				else
				{
						log.error("Not Support");
						return false;
				}

				if(vars->serversocketfd < 0)
				{
					log.error(" open socket fail ");
					return false;
				}
				//Set recvBuf  cache
				setsockopt(vars->serversocketfd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

				//set sendBuf  cache
				setsockopt(vars->serversocketfd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

				//  binder  Server Address 你是说这里绑定的??
				utility::memorySet(0,&vars->server,sizeof(struct sockaddr_in));
				vars->server.sin_family      =  AF_INET;
				vars->server.sin_port        =  htons(portNumber);//转接成网络字节函数
				vars->server.sin_addr.s_addr =  htonl(INADDR_ANY);//开放所有网卡地址

				if(bind(vars->serversocketfd,(struct sockaddr *)&vars->server,sizeof(vars->server)) == -1)
				{
					log.error(" BINDER SERVER FAIL");
					return  false;
				}

				// set non block
				if (fcntl(vars->serversocketfd, F_SETFL, O_NONBLOCK) == -1)
							log.error("non block mode failed");
				// UDP  Protocol   Do not Need  listen  and  accept client
				if(protocol == TM_UDP)
				{
					bool bBroadcast=true;
					setsockopt(vars->serversocketfd,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(bool));
					return TRUE;
				}
				// listen   ClientS   and  accept client
				if(protocol == TM_TCP  )
				{
							if( listen(vars->serversocketfd,1) == -1)
							{
								log.error(" Listen Fail");
								return false;
							}

							Timer timenow ;
							timenow.start();

							while(true)
							{
									if(timenow.check() < timeout )
									{
											struct sockaddr_in        clientaddr ;
											socklen_t   len = sizeof(clientaddr) ;
											char  buffer[20]   ;
											vars->clientsocketfd  = accept(vars->serversocketfd,(struct sockaddr*)&clientaddr,&len);
											if(  vars->clientsocketfd   > 0)
											{
												inet_ntop(AF_INET,&(clientaddr.sin_addr.s_addr),buffer,20);
												log.error((String)"Client IP :"+ (String)buffer);
												//Set recvBuf  cache
												setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
												//set sendBuf  cache
												setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

												// set client socket fd no blocking
												// set non block
												if (fcntl(vars->clientsocketfd, F_SETFL, O_NONBLOCK) == -1)
														log.error("client non block mode failed");
												return  true;
											}
									}
									else
									{
											log.error(" Time Out. Accept CLient Fail.");
											return false;
									}
							}
				}
}


max_min_ 2013-11-05
  • 打赏
  • 举报
回复
引用 5 楼 yikesong321 的回复:
client端代码:

//Connect to Server
int result = 0;
result     = connect(vars->clientsocketfd,(struct sockaddr *)&vars->client,sizeof(vars->client)) ;
if( result == 0)
		    return true;
else if((errno == EINPROGRESS))
{
	timeval    tm  ;
	fd_set     set ;
	Int  len   = sizeof(int) ;
	int  socketERROR =           -1 ;
	tm.tv_sec  =            0 ;
	tm.tv_usec = timeout*1000 ;
	FD_ZERO( &set ) ;
	FD_SET(vars->clientsocketfd, &set);
	if( select((int)vars->clientsocketfd + 1 , NULL, &set, NULL, &tm) > 0)
	{
			if(FD_ISSET(vars->clientsocketfd,&set))
			{
					if(getsockopt(vars->clientsocketfd, SOL_SOCKET, SO_ERROR, (void *)&socketERROR, &len) == 0)
					{
							if(socketERROR == 0)
							{
								log.error((String)" Connect Server successful  Result :  " + result);
								return true;
							}
					}
			}
	}
}


不是这个,我说的是你在建立socket的时候,是否绑定了端口号呢? 把绑定端口号服务端客户端的代码贴上来看看!
yikesong321 2013-11-05
  • 打赏
  • 举报
回复
client端代码:

//Connect to Server
int result = 0;
result     = connect(vars->clientsocketfd,(struct sockaddr *)&vars->client,sizeof(vars->client)) ;
if( result == 0)
		    return true;
else if((errno == EINPROGRESS))
{
	timeval    tm  ;
	fd_set     set ;
	Int  len   = sizeof(int) ;
	int  socketERROR =           -1 ;
	tm.tv_sec  =            0 ;
	tm.tv_usec = timeout*1000 ;
	FD_ZERO( &set ) ;
	FD_SET(vars->clientsocketfd, &set);
	if( select((int)vars->clientsocketfd + 1 , NULL, &set, NULL, &tm) > 0)
	{
			if(FD_ISSET(vars->clientsocketfd,&set))
			{
					if(getsockopt(vars->clientsocketfd, SOL_SOCKET, SO_ERROR, (void *)&socketERROR, &len) == 0)
					{
							if(socketERROR == 0)
							{
								log.error((String)" Connect Server successful  Result :  " + result);
								return true;
							}
					}
			}
	}
}


yikesong321 2013-11-05
  • 打赏
  • 举报
回复
这个格式有问题。重新传一下 server端的代码

if( listen(vars->serversocketfd,1) == -1)
{
	log.error(" Server Socket Listen Fail.");
	return false;
}
	Timer     timenow ;
	timenow.start()   ;
while(true)
{
	if(timenow.check() < timeout )
	{
		struct sockaddr_in           clientaddr         ;
		socklen_t len           =    sizeof(clientaddr) ;
		char                         buffer[20]         ;
		vars->clientsocketfd    =    accept(vars->serversocketfd,(struct sockaddr*)&clientaddr,&len) ;
		if( vars->clientsocketfd   !=   INVALID_SOCKET  )
		{
					inet_ntop(  AF_INET,  &(clientaddr.sin_addr.S_un.S_addr) ,   buffer,    20) ;
					log.error((String)"Accept Client Successful   IP  :      "+ (String)buffer) ;
					//Set recvBuf  cache 128KB
					setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
					//set sendBuf  cache 128KB
					setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
					int     result   =  ioctlsocket(vars->clientsocketfd,FIONBIO,&flag) ;
					if (    result !=  NO_ERROR   ) 
					{
						log.error("non block mode failed  " );
						return false;
					}
					return  true;
		}
	}
	else
	{
			log.error((String)"Time out , Accept Client  Failed");
	  	return false;
	} 
} 

yikesong321 2013-11-05
  • 打赏
  • 举报
回复
恩。下面是2端建立连接的代码 这是Server端,2端的socket都被我设置成了非阻塞。

while(true)
{
// 设置超过规定的timeout就退出											        if(timenow.check() < timeout )
{												struct sockaddr_in        clientaddr ;												socklen_t   len = sizeof(clientaddr) ;												char  buffer[20]   ;												vars->clientsocketfd  = accept(vars->serversocketfd,(struct sockaddr*)&clientaddr,&len);												if(  vars->clientsocketfd   > 0)												{													inet_ntop(AF_INET,&(clientaddr.sin_addr.s_addr),buffer,20);													log.error((String)"Client IP :"+ (String)buffer);													//Set recvBuf  cache													setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));													//set sendBuf  cache													setsockopt(vars->clientsocketfd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));													if (fcntl(vars->clientsocketfd, F_SETFL, O_NONBLOCK) == -1)															 log.error("client non block mode failed");													return  true;												}
}
else
{												log.error(" Time Out. Accept CLient Fail.");												              return false;											}
}

这是client端的代码,socket也是非阻塞的

while(true)
{
// 设置超时退出
if(timenow.check() < timeout )
{
int result = 0;
result  = connect(vars->clientsocketfd,(struct sockaddr *)&vars->client,sizeof(vars->client)) ;
if( result == 0)
	return true;
else if((errno == EINPROGRESS))
{
	timeval    tm  ;
	fd_set     set ;
	Int  len   = sizeof(int) ;
	int  socketERROR =           -1 ;
	tm.tv_sec  =            0 ;
	tm.tv_usec = timeout*1000 ;

	FD_ZERO( &set ) ;
	FD_SET(vars->clientsocketfd, &set);
if( select((int)vars->clientsocketfd + 1 , NULL, &set, NULL, &tm) > 0)
{

if(FD_ISSET(vars->clientsocketfd,&set))
{
if(getsockopt(vars->clientsocketfd, SOL_SOCKET, SO_ERROR, (void *)&socketERROR, (socklen_t *)&len) == 0)
{												 if(socketERROR == 0)												{														log.error((String)" Connect Server successful  Result :  " + result);																												return true;												}
}
}
}
}
}
else
{
	log.error("Time out , connect Server Fail.");
	return FALSE;
}
}





beginning1126 2013-11-04
  • 打赏
  • 举报
回复
server端代码是循环执行的吗?
max_min_ 2013-11-04
  • 打赏
  • 举报
回复
把两端的建立socket这些 贴出来看看!端口是否绑定成功? 怀疑是端口问题呢!

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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