WinSock的同步异步、阻塞非阻塞问题

yuhaouestc 2017-06-27 03:38:13
用了别人写得程序,但是没搞懂。。。
用的select模型,是不是就是同步的方式,那阻塞和非阻塞有是怎么判断的呢

Init里面就是连接和接收数据

TcpInit()
{
if (!m_bClientConnected)
{
int m_nPortRemote = 5025;
CString m_strRemoteIP = _T("192.168.1.58");
DWORD IP = inet_addr((LPCTSTR)m_strRemoteIP);
if(!m_pSockClient->Connect(m_strRemoteIP,m_nPortRemote))
{
int a=0;
return;
}
if(!m_pSockClient->StartReceiving(TcpStatusChangeCallBack,TcpRecvCallBack,(DWORD)this))
{
int a=0;
m_pSockClient->Close();
return;
}
m_bClientConnected=TRUE;
}
WriteCmd("FORMat:DATA INT,16\n",20);
}

接收数据里面开启了一个线程,并且有两个回调函数,一个状态一个数据

StartReceiving(LPStatusProc proc1,LPDataArriveProc proc2,DWORD userdata)
{
if(!m_bAvailable)
{
return FALSE;
}
if(m_nType==TCP_SOCKET_SERVER)
{
return FALSE;
}
if(!m_bCreated)
{
return FALSE;
}
if(m_bAuto)
{
return FALSE;
}

//开始自动接收
m_lpClientStatusProc=proc1;
m_lpClientDataArriveProc=proc2;
m_dwUserData=userdata;
m_bAuto=TRUE;

DWORD dwThreadId;

m_hServerThread=CreateThread(NULL,0,ClientThread,this,0,&dwThreadId);

if(m_hServerThread==NULL)
{
m_bAuto=FALSE;
error=WSAGetLastError();
return FALSE;
}

return TRUE;
}

客户端线程
ClientThread(LPVOID lpParameter)
{
CTCPSocket* m_pTCP=(CTCPSocket*)lpParameter;

int nRet;
char buf[256];

timeval tv={0,5000};
fd_set fs;

//不断接收服务器发来数据
while(m_pTCP->m_bAuto)
{
FD_ZERO(&fs);
FD_SET(m_pTCP->m_sSocket,&fs);
if(select(1,&fs,NULL,NULL,&tv)==1)
{
nRet=recv(m_pTCP->m_sSocket,buf,256,0);

if(nRet==SOCKET_ERROR)
{
//出错断开(例如服务器关闭)
m_pTCP->error=WSAGetLastError();
closesocket(m_pTCP->m_sSocket);
m_pTCP->m_bAuto=FALSE;
TRACE("客户端出错断开! \n");

//回调处理
if(m_pTCP->m_lpClientStatusProc!=NULL)
{
char* inf;
inf=new char[22];
inf[0]='C';
inf[1]='D';
m_pTCP->m_lpClientStatusProc(inf,22,m_pTCP->m_dwUserData);
delete inf;
}

break;
}

if(nRet>0)
{
//收到新的数据
//TRACE("客户端收到数据%d字节! \n",nRet);

//数据回调处理
if(m_pTCP->m_lpClientDataArriveProc!=NULL)
{
char* inf;
inf=new char[nRet];
memcpy(inf,buf,nRet);
m_pTCP->m_lpClientDataArriveProc(inf,nRet,m_pTCP->m_dwUserData);
delete inf;
}

continue;
}

if(nRet==0)
{
//服务器正常断开
TRACE("客户端正常断开! \n");

//回调处理
if(m_pTCP->m_lpClientStatusProc!=NULL)
{
char* inf;
inf=new char[22];
inf[0]='C';
inf[1]='D';
m_pTCP->m_lpClientStatusProc(inf,22,m_pTCP->m_dwUserData);
delete inf;
}
closesocket(m_pTCP->m_sSocket);
m_pTCP->m_bAuto=FALSE;

break;
}
}
}

return 0;
}
...全文
339 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-06-29
  • 打赏
  • 举报
回复
赵4老师 2017-06-29
  • 打赏
  • 举报
回复
用事实说话,焦点访谈; 用代码说话,真程序员。
赵4老师 2017-06-28
  • 打赏
  • 举报
回复
MSDN98_1\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\IOCTL.C
/******************************************************************************\
* ioctl.c - TCP server
*
*       This is a part of the Microsoft Source Code Samples.
*       Copyright 1996-1997 Microsoft Corporation.
*       All rights reserved.
*       This source code is only intended as a supplement to
*       Microsoft Development Tools and/or WinHelp documentation.
*       See these sources for detailed information regarding the
*       Microsoft samples programs.
\******************************************************************************/



#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define DEFAULT_PORT 5001

int ReadAndEcho(SOCKET , char *,int ) ;
int WriteMessage(SOCKET , char *,int ) ;

void Usage(char *progname) {
	fprintf(stderr,"Usage\n%s -e [endpoint] -i [interface]\n",
		progname);
	fprintf(stderr,"Where:\n");
	fprintf(stderr,"\tendpoint is the port to listen on\n");
	fprintf(stderr,"\tinterface is the ipaddr (in dotted decimal notation)");
	fprintf(stderr," to bind to\n");
	fprintf(stderr,"Defaults are 5001 and INADDR_ANY\n");
	WSACleanup();
	exit(1);
}
int main(int argc, char **argv) {

	char Buffer[128];
	char *interface= NULL;
	unsigned short port=DEFAULT_PORT;
	int	fromlen;
	int	i, ioctl_opt =1;
	struct sockaddr_in local, from;
	WSADATA	wsaData;
	SOCKET listen_socket, msgsock;
	fd_set readfds,	writefds, exceptfds;

	/* Parse arguments */
	if (argc >1) {
		for(i=1;i <argc;i++) {
			if ( (argv[i][0] ==	'-') || (argv[i][0] == '/') ) {
				switch(tolower(argv[i][1]))	{
					case 'i':
						interface =	argv[++i];
						break;
					case 'e':
						port = atoi(argv[++i]);
						break;
					default:
						Usage(argv[0]);
						break;
				}
			}
			else
				Usage(argv[0]);
		}
	}
 
	if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR)	{
		fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
 
	if (port ==	0){
		Usage(argv[0]);
	}

	//
	// The fd sets should be zeroed	out	before using them to prevent errors.
	FD_ZERO(&readfds);
	FD_ZERO(&writefds);
	FD_ZERO(&exceptfds);
	memset(Buffer,0,sizeof(Buffer));

	local.sin_family = AF_INET;

	//
	// bind	to specific	interface if desired.

	local.sin_addr.s_addr =	(!interface)?INADDR_ANY:inet_addr(interface);

	/*
	 * Port	MUST be	in Network Byte	Order
	 */
	local.sin_port = htons(port);

	listen_socket =	socket(AF_INET,	SOCK_STREAM,0);	// TCP socket
	if (listen_socket == INVALID_SOCKET){
		fprintf(stderr,"socket() failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
	//
	// bind() associates a local address and port combination with the
	// socket just created.

	if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local) )
		== SOCKET_ERROR) {
		fprintf(stderr,"bind() failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//
	// start listening on the socket for incoming connections
	//
	if (listen(listen_socket,5)	== SOCKET_ERROR) {
		fprintf(stderr,"listen() failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
	printf("%s: Listening on port %d\n",argv[0],port);

	//
	// Set the socket to non-blocking mode.
	//
	if (ioctlsocket(listen_socket,FIONBIO,&ioctl_opt) == SOCKET_ERROR) {
		fprintf(stderr,"ioctlsocket failed %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
	//
	// The structure of	the	loop below is very simple. We only accept one
	// connection at a time. As	soon as	another	client connects, we
	// disconnect the first	one, and start talking to the new client.
	// All this	server does	is to echo the data	received on	the	socket
	// back	to the client.
	//
	// This	is not a very realistic	server,	but	it does	serve to show that
	// select()	does not scale very	well on	win32. If we were dealing
	// with	more than one client, we would have	to have	a list of sockets
	// that	are	in each	fdset to be	able to	check them when	select()
	// returns.
	//
	while(1) {

		//
		// A socket	in the listen()	state becomes ready	to read	when a
		// client connects to it. An accept() will complete	without
		// blocking.
		// Since select	sets the sockets that are ready	to be read from	or
		// written to, we have to include listen_socket	in the fdset each time
		// through the loop.
		//

		FD_SET(listen_socket,&readfds);

		i =	select(0,&readfds,&writefds,&exceptfds,NULL);
		if (i == SOCKET_ERROR) {
			fprintf(stderr,"select failed %d\n",WSAGetLastError());
		}
		if (i==0){
			fprintf(stderr,"Select returned no fds ready\n");
		}

		if (FD_ISSET(listen_socket,	&readfds)){
			//
			// close the previous client socket.
			// We must also	clear it from the fdset	to prevent select()
			// from	failing.
			//
			closesocket(msgsock);
			FD_CLR(msgsock,&readfds);
			FD_CLR(msgsock,&writefds);
			fromlen	= sizeof(from);
			msgsock= accept(listen_socket,(struct sockaddr*)&from,&fromlen);
			if (msgsock == INVALID_SOCKET) {
				fprintf(stderr,"accept failed %d\n",WSAGetLastError());
				WSACleanup();
				return -1;
			}
			FD_SET(msgsock,&writefds);
			FD_SET(msgsock,&readfds);
			continue;
		}
		if (FD_ISSET(msgsock,&readfds) ) {
			//
			// socket is ready to read, i.e., there is data on the socket.
			//
			if (ReadAndEcho(msgsock,Buffer,sizeof(Buffer))<0) {
				fprintf(stderr,"terminating connection\n");
				FD_CLR(msgsock,&readfds);
				FD_CLR(msgsock,&writefds);
				closesocket(msgsock);
				continue;
			}
		}
		if (FD_ISSET(msgsock,&writefds) ){
			if (WriteMessage(msgsock,Buffer,sizeof(Buffer)) <=0) {
				fprintf(stderr,"terminating connection\n");
				FD_CLR(msgsock,&readfds);
				FD_CLR(msgsock,&writefds);
				closesocket(msgsock);
				continue;
			}
		}
		FD_SET(msgsock,&writefds);
		FD_SET(msgsock,&readfds);
	}
}
int ReadAndEcho(SOCKET insock, char *Buffer,int size) {
	int rc;

	rc = recv(insock,Buffer,size,0);

	if (rc == SOCKET_ERROR) {
		fprintf(stderr,"recv() failed with error %d\n",WSAGetLastError());	
		return -1;
	}
	if (rc ==0) {
		fprintf(stderr,"Connection closed by client\n");
		return 0;
	}
	printf("Received [%s] from client\n",Buffer);
	return rc;
}
int WriteMessage(SOCKET outsock, char *Buffer,int size) {
	int rc;
	int lasterr;

	printf("Sending [%s] to client\n",Buffer);
	rc = send(outsock,Buffer,size, 0);

	if (rc == SOCKET_ERROR) {
	  lasterr = WSAGetLastError();
	  if (lasterr == WSAEWOULDBLOCK)
		return 0;
	  else {
		fprintf(stderr,"send() failed with error %d\n",lasterr);	
		return -1;
	  }
	}
	if (rc ==0) {
		fprintf(stderr,"Connection closed by client\n");
	}
	return rc;
}
赵4老师 2017-06-28
  • 打赏
  • 举报
回复
MSDN98_1\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\SIMPLES.C
/******************************************************************************\
* simples.c - Simple TCP/UDP server using Winsock 1.1
*       This is a part of the Microsoft Source Code Samples.
*       Copyright 1996-1997 Microsoft Corporation.
*       All rights reserved.
*       This source code is only intended as a supplement to
*       Microsoft Development Tools and/or WinHelp documentation.
*       See these sources for detailed information regarding the
*       Microsoft samples programs.
\******************************************************************************/

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define DEFAULT_PORT 5001
#define DEFAULT_PROTO SOCK_STREAM // TCP

void Usage(char *progname) {
	fprintf(stderr,"Usage\n%s -p [protocol] -e [endpoint] -i [interface]\n",
		progname);
	fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n");
	fprintf(stderr,"\tendpoint is the port to listen on\n");
	fprintf(stderr,"\tinterface is the ipaddr (in dotted decimal notation)");
	fprintf(stderr," to bind to\n");
	fprintf(stderr,"Defaults are TCP,5001 and INADDR_ANY\n");
	WSACleanup();
	exit(1);
}
int main(int argc, char **argv) {

	char Buffer[128];
	char *interface= NULL;
	unsigned short port=DEFAULT_PORT;
	int	retval;
	int	fromlen;
	int	i;
	int	socket_type	= DEFAULT_PROTO;
	struct sockaddr_in local, from;
	WSADATA	wsaData;
	SOCKET listen_socket, msgsock;

	/* Parse arguments */
	if (argc >1) {
		for(i=1;i <argc;i++) {
			if ( (argv[i][0] ==	'-') || (argv[i][0] == '/') ) {
				switch(tolower(argv[i][1]))	{
					case 'p':
						if (!stricmp(argv[i+1],	"TCP") )
							socket_type	= SOCK_STREAM;
						else if	(!stricmp(argv[i+1], "UDP") )
							socket_type	= SOCK_DGRAM;
						else
							Usage(argv[0]);
						i++;
						break;

					case 'i':
						interface = argv[++i];
						break;
					case 'e':
						port = atoi(argv[++i]);
						break;
					default:
						Usage(argv[0]);
						break;
				}
			}
			else
				Usage(argv[0]);
		}
	}
	
	if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
		fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
	
	if (port == 0){
		Usage(argv[0]);
	}

	local.sin_family = AF_INET;
	local.sin_addr.s_addr = (!interface)?INADDR_ANY:inet_addr(interface);

	/*
	 * Port MUST be in Network Byte Order
	 */
	local.sin_port = htons(port);

	listen_socket = socket(AF_INET, socket_type,0); // TCP socket
	
	if (listen_socket == INVALID_SOCKET){
		fprintf(stderr,"socket() failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
	//
	// bind() associates a local address and port combination with the
	// socket just created. This is most useful when the application is a
	// server that has a well-known port that clients know about in advance.
	//

	if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local) )
		== SOCKET_ERROR) {
		fprintf(stderr,"bind() failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//
	// So far, everything we did was applicable to TCP as well as UDP.
	// However, there are certain steps that do not work when the server is
	// using UDP.
	//

	// We cannot listen() on a UDP socket.

	if (socket_type != SOCK_DGRAM) {
		if (listen(listen_socket,5) == SOCKET_ERROR) {
			fprintf(stderr,"listen() failed with error %d\n",WSAGetLastError());
			WSACleanup();
			return -1;
		}
	}
	printf("%s: 'Listening' on port %d, protocol %s\n",argv[0],port,
		(socket_type == SOCK_STREAM)?"TCP":"UDP");
	while(1) {
		fromlen =sizeof(from);
		//
		// accept() doesn't make sense on UDP, since we do not listen()
		//
		if (socket_type != SOCK_DGRAM) {
			msgsock = accept(listen_socket,(struct sockaddr*)&from, &fromlen);
			if (msgsock == INVALID_SOCKET) {
				fprintf(stderr,"accept() error %d\n",WSAGetLastError());
				WSACleanup();
				return -1;
			}
			printf("accepted connection from %s, port %d\n",
						inet_ntoa(from.sin_addr),
						htons(from.sin_port)) ;
			
		}
		else
			msgsock = listen_socket;

		//
		// In the case of SOCK_STREAM, the server can do recv() and
		// send() on the accepted socket and then close it.

		// However, for SOCK_DGRAM (UDP), the server will do
		// recvfrom() and sendto()  in a loop.

		if (socket_type != SOCK_DGRAM)
			retval = recv(msgsock,Buffer,sizeof (Buffer),0 );
		else {
			retval = recvfrom(msgsock,Buffer,sizeof (Buffer),0,
				(struct sockaddr *)&from,&fromlen);
			printf("Received datagram from %s\n",inet_ntoa(from.sin_addr));
		}
			
		if (retval == SOCKET_ERROR) {
			fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
			closesocket(msgsock);
			continue;
		}
		if (retval == 0) {
			printf("Client closed connection\n");
			closesocket(msgsock);
			continue;
		}
		printf("Received %d bytes, data [%s] from client\n",retval,Buffer);

		printf("Echoing same data back to client\n");
		if (socket_type != SOCK_DGRAM)
			retval = send(msgsock,Buffer,sizeof(Buffer),0);
		else
			retval = sendto(msgsock,Buffer,sizeof (Buffer),0,
				(struct sockaddr *)&from,fromlen);
		if (retval == SOCKET_ERROR) {
			fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
		}
		if (socket_type != SOCK_DGRAM){
			printf("Terminating connection\n");
			closesocket(msgsock);
		}
		else
			printf("UDP server looping back for more requests\n");
		continue;
	}
}
赵4老师 2017-06-28
  • 打赏
  • 举报
回复
仅供参考: MSDN98_1\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\SIMPLEC.C
/******************************************************************************\
* simplec.c - Simple TCP/UDP client using Winsock 1.1
*
*       This is a part of the Microsoft Source Code Samples.
*       Copyright 1996-1997 Microsoft Corporation.
*       All rights reserved.
*       This source code is only intended as a supplement to
*       Microsoft Development Tools and/or WinHelp documentation.
*       See these sources for detailed information regarding the
*       Microsoft samples programs.
\******************************************************************************/

#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define DEFAULT_PORT 5001
#define DEFAULT_PROTO SOCK_STREAM // TCP

void Usage(char *progname) {
	fprintf(stderr,"Usage\n%s -p [protocol] -n [server] -e [endpoint] \
	-l [iterations]\n",
		progname);
	fprintf(stderr,"Where:\n\tprotocol is one of TCP or UDP\n");
	fprintf(stderr,"\tserver is the IP address or name of server\n");
	fprintf(stderr,"\tendpoint is the port to listen on\n");
	fprintf(stderr,"\titerations is the number of loops to execute\n");
	fprintf(stderr,"\t(-l by itself makes client run in an infinite loop,");
	fprintf(stderr," Hit Ctrl-C to terminate it)\n");
	fprintf(stderr,"Defaults are TCP , localhost and 5001\n");
	WSACleanup();
	exit(1);
}
int main(int argc, char **argv) {

	char Buffer[128];
	char *server_name= "localhost";
	unsigned short port	= DEFAULT_PORT;
	int	retval,	loopflag=0;
	int	i, loopcount,maxloop=-1;
	unsigned int addr;
	int	socket_type	= DEFAULT_PROTO;
	struct sockaddr_in server;
	struct hostent *hp;
	WSADATA	wsaData;
	SOCKET	conn_socket;

	if (argc >1) {
		for(i=1;i <argc;i++) {
			if ( (argv[i][0] ==	'-') || (argv[i][0] == '/') ) {
				switch(tolower(argv[i][1]))	{
					case 'p':
						if (!stricmp(argv[i+1],	"TCP") )
							socket_type	= SOCK_STREAM;
						else if	(!stricmp(argv[i+1], "UDP") )
							socket_type	= SOCK_DGRAM;
						else
							Usage(argv[0]);
						i++;
						break;

					case 'n':
						server_name	= argv[++i];
						break;
					case 'e':
						port = atoi(argv[++i]);
						break;
					case 'l':
						loopflag =1;
						if (argv[i+1]) {
							if (argv[i+1][0] !=	'-')
								maxloop	= atoi(argv[i+1]);
						}
						else
							maxloop	= -1;
						i++;
						break;
					default:
						Usage(argv[0]);
						break;
				}
			}
			else
				Usage(argv[0]);
		}
	}
 
	if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR)	{
		fprintf(stderr,"WSAStartup failed with error %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}
 
	if (port ==	0){
		Usage(argv[0]);
	}

	//
	// Attempt to detect if	we should call gethostbyname() or
	// gethostbyaddr()

	if (isalpha(server_name[0])) {	 /*	server address is a	name */
		hp = gethostbyname(server_name);
	}
	else  {	/* Convert nnn.nnn address to a	usable one */
		addr = inet_addr(server_name);
		hp = gethostbyaddr((char *)&addr,4,AF_INET);
	}
	if (hp == NULL ) {
		fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d\n",
			server_name,WSAGetLastError());
		WSACleanup();
		exit(1);
	}

	//
	// Copy	the	resolved information into the sockaddr_in structure
	//
	memset(&server,0,sizeof(server));
	memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
	server.sin_family =	hp->h_addrtype;
	server.sin_port	= htons(port);

	conn_socket	= socket(AF_INET,socket_type,0); /*	Open a socket */
	if (conn_socket	<0 ) {
		fprintf(stderr,"Client: Error Opening socket: Error %d\n",
			WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//
	// Notice that nothing in this code	is specific	to whether we
	// are using UDP or	TCP.
	// We achieve this by using	a simple trick.
	//	  When connect() is	called on a	datagram socket, it	does not
	//	  actually establish the connection	as a stream	(TCP) socket
	//	  would. Instead, TCP/IP establishes the remote	half of	the
	//	  (	LocalIPAddress,	LocalPort, RemoteIP, RemotePort) mapping.
	//	  This enables us to use send()	and	recv() on datagram sockets,
	//	  instead of recvfrom()	and	sendto()


	printf("Client connecting to: %s\n",hp->h_name);
	if (connect(conn_socket,(struct	sockaddr*)&server,sizeof(server))
		== SOCKET_ERROR) {
		fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
		WSACleanup();
		return -1;
	}

	// cook	up a string	to send
	//
	loopcount =0;
	while(1) {
		wsprintf(Buffer,"This is a small test message [number %d]",loopcount++);
		retval = send(conn_socket,Buffer,sizeof(Buffer),0);
		if (retval == SOCKET_ERROR)	{
			fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
			WSACleanup();
			return -1;
		}
		printf("Sent Data [%s]\n",Buffer);
		retval = recv(conn_socket,Buffer,sizeof	(Buffer),0 );
		if (retval == SOCKET_ERROR)	{
			fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
			closesocket(conn_socket);
			WSACleanup();
			return -1;
		}
		//
		// We are not likely to	see	this with UDP, since there is no
		// 'connection' established.
		//
		if (retval == 0) {
			printf("Server closed connection\n");
			closesocket(conn_socket);
			WSACleanup();
			return -1;
		}
		printf("Received %d bytes, data [%s] from server\n",retval,Buffer);
		if (!loopflag){
			printf("Terminating connection\n");
			break;
		}
		else {
			if ( (loopcount	>= maxloop)	&& (maxloop	>0)	)
				break;
		}
	}
	closesocket(conn_socket);
	WSACleanup();
}
xiaohuh421 2017-06-28
  • 打赏
  • 举报
回复
什么叫异步阻塞....... 没有这种说法.
yuhaouestc 2017-06-28
  • 打赏
  • 举报
回复
引用 6 楼 xiaohuh421 的回复:
是否阻塞, 是看socket有没有设置非阻塞模式, 默认创建的socket都是阻塞模式, 需要调用api ioctlsocket设置非阻塞模式. select一般都是为了把非阻塞模式的, 变成阻塞模式. 为何这么做, 为什么不直接使用阻塞模式呢? 因为select可以同时判断多个socket连接中是否有数据可以接收, 阻塞模式做不到. 并且同时也能做到没有数据的时候,阻塞等待有数据才做事情, 不会浪费CPU. 有阻塞模式的相同的好处. 再并且, 还可方便的设置接收超时. 跟阻塞模式一样.
恩,那上面那个程序应该就是同步阻塞的?
xiaohuh421 2017-06-28
  • 打赏
  • 举报
回复
是否阻塞, 是看socket有没有设置非阻塞模式, 默认创建的socket都是阻塞模式, 需要调用api ioctlsocket设置非阻塞模式. select一般都是为了把非阻塞模式的, 变成阻塞模式. 为何这么做, 为什么不直接使用阻塞模式呢? 因为select可以同时判断多个socket连接中是否有数据可以接收, 阻塞模式做不到. 并且同时也能做到没有数据的时候,阻塞等待有数据才做事情, 不会浪费CPU. 有阻塞模式的相同的好处. 再并且, 还可方便的设置接收超时. 跟阻塞模式一样.
worldy 2017-06-28
  • 打赏
  • 举报
回复
同步是阻塞的,异步是非阻塞的,所谓阻塞,就是你发送数据,然后等待返回数据,数据没有返回,就死等,直到数据返回或者超时; 非阻塞是你发出一个接收命令,命令发出后不管数据有没有收到,就执行代码的后面的指令,而当数据返回后,系统发出事件通知你处理接收到的数据,这种模式是非阻塞,是异步的
yuhaouestc 2017-06-27
  • 打赏
  • 举报
回复
感觉是同步阻塞的方式?能不能改成非阻塞呢

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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