示例#1
0
文件: gsocket.c 项目: EdgarTx/wx
int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
{
	OTFlags flags ;
	OTResult res ;
	OTByteCount sz = 0 ;

  	OTCountDataBytes( socket->m_endpoint , &sz ) ;
  	if ( size > (int)sz )
  	  size = sz ;
	res = OTRcv( socket->m_endpoint , buffer , size , &flags ) ;
	if ( res < 0 )
	{
		return -1 ;
	}
	
	// we simulate another read event if there are still bytes
	if ( socket->m_takesEvents )
	{
  		OTByteCount sz = 0 ;
  		OTCountDataBytes( socket->m_endpoint , &sz ) ;
  		if ( sz > 0 )
  		{
        	socket->m_detected |= GSOCK_INPUT_FLAG ;
			(socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]);
 		}
 	}
 	return res ;
}
示例#2
0
// no modified.. waiting for a MAC!
int	my_recv(TCPsocket sock, void *data, int maxlen)
{
	int len = 0;
	OSStatus res;
	/* Server sockets are for accepting connections only */
	if ( sock->sflag ) {
		SDLNet_SetError("Server sockets cannot receive");
		return(-1);
	}
	do
	{
		res = OTRcv(sock->channel, data, maxlen-len, 0);
		if (res > 0) {
			len = res;
		}
		AsyncTCPPopEvent(sock);
		if( res == kOTLookErr )
		{
			res = OTLook(sock->channel );
			continue;
		}
	} while ( (len == 0) && (res == kOTNoDataErr) );

	sock->ready = 0;
	if ( len == 0 ) { /* Open Transport error */
		return(-1);
	}
	return(len);
}
示例#3
0
int recv(int s, char *buffer, size_t buflen, int flags)
{
	OTFlags 	junkFlags;
	int n = OTRcv(ep, (void *) buffer, buflen, &junkFlags);
	if( n <= 0 )
		return n;
	return n;
}
/*---------------------------------------------------------------------------*/
static int32 AGNetRead(AGNetCtx *ctx, AGSocket *soc, uint8 *buffer,
                       int32 bytes, AGBool block)
{
    OTFlags junkFlags = 0;

    if (NULL == ctx || NULL == soc || NULL == buffer)
        return AG_NET_ERROR;
        
    return AGNetMacMapError(OTRcv(soc->ep,
                                (void *) buffer,
                                bytes,
                                &junkFlags));
}
示例#5
0
/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
   and store them in the buffer pointed to by 'data'.
   This function returns the actual amount of data received.  If the return
   value is less than or equal to zero, then either the remote connection was
   closed, or an unknown socket error occurred.
*/
int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen)
{
	int len = 0;
	OSStatus res;
	/* Server sockets are for accepting connections only */
	if ( sock->sflag ) {
		SDLNet_SetError("Server sockets cannot receive");
		return(-1);
	}

	do
	{
		res = OTRcv(sock->channel, data, maxlen-len, 0);
		if (res > 0) {
			len = res;
		}

#ifdef DEBUG_NET
		if ( res != kOTNoDataErr )
			printf("SDLNet_TCP_Recv received ; %d\n", res );
#endif
		
		AsyncTCPPopEvent(sock);
		if( res == kOTLookErr )
		{
			res = OTLook(sock->channel );
			continue;
		}
	} while ( (len == 0) && (res == kOTNoDataErr) );

	sock->ready = 0;
	if ( len == 0 ) { /* Open Transport error */
#ifdef DEBUG_NET
		printf("Open Transport error: %d\n", res);
#endif
		return(-1);
	}
	return(len);
}
示例#6
0
// Errors:
// EBADF -- bad socket id
// EFAULT -- bad buffer
static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, 
                               PRIntn flags, PRIntervalTime timeout, SndRcvOpCode opCode)
{
	OSStatus err;
	OTResult result;
	PRInt32 osfd = fd->secret->md.osfd;
	EndpointRef endpoint = (EndpointRef) osfd;
	PRThread *me = _PR_MD_CURRENT_THREAD();
	PRInt32 bytesLeft = amount;

	PR_ASSERT(flags == 0);
	
	if (endpoint == NULL) {
		err = kEBADFErr;
		goto ErrorExit;
	}
		
	if (buf == NULL) {
		err = kEFAULTErr;
		goto ErrorExit;
	}
		
	while (bytesLeft > 0) {
	
		PrepareThreadForAsyncIO(me, endpoint, osfd);    

		if (opCode == kSTREAM_SEND)
			result = OTSnd(endpoint, buf, bytesLeft, NULL);
		else if (opCode == kSTREAM_RECEIVE)
			result = OTRcv(endpoint, buf, bytesLeft, NULL);
		else {
			err = kEINVALErr;
			goto ErrorExit;
		}

		if (result > 0) {
			buf = (void *) ( (UInt32) buf + (UInt32)result );
			bytesLeft -= result;
    		me->io_pending = PR_FALSE;
    		if (opCode == kSTREAM_RECEIVE)
    			return result;
		} else {
			if (result == kOTOutStateErr) { /* it has been closed */
				return 0;
			}
			if (result == kOTLookErr) {
				PRBool readReady,writeReady,exceptReady;
				/* process the event and then continue the operation */
				(void) GetState(endpoint, &readReady, &writeReady, &exceptReady);
				continue;
			}
			if (result != kOTNoDataErr && result != kOTFlowErr && 
			    result != kEAGAINErr && result != kEWOULDBLOCKErr) {
				err = result;
				goto ErrorExit;
			} else if (fd->secret->nonblocking) {
    			me->io_pending = PR_FALSE;
				err = result;
				goto ErrorExit;
			}
			WaitOnThisThread(me, timeout);
			err = me->md.osErrCode;
			if (err != kOTNoError)
				goto ErrorExit;

			PR_ASSERT(me->md.cookie != NULL);
		}
	}

	return amount;

ErrorExit:
	macsock_map_error(err);
    return -1;
}                               
示例#7
0
void ottcp_handleIncomingData(OTTCP *x) {
	/* Here's where we actually do the read.  This is called by our notifier, so it
  	   will run at "deferred task time", i.e., interrupt level.  */
	
	OTFlags flags;
	OTResult r;
	short oldLockout;

	EnterCallback();

//	post("** Entering ottcp_handleIncomingData");

	// Are we in a state where we want to read data that comes in?
	
	if (x->o_state == SETTING_UP) {
		post("е OTTCP: How could ottcp_handleIncomingData() be called in state SETTING_UP?");
	} else if (x->o_state == NO_REQUEST) {
		// The rest of this Max program hasn't asked us for any data yet, so
		// we won't read it out of OpenTransport.  That way, when OT's buffers
		// fill up, TCP flow control will happen correctly.
		x->o_datawaiting = 1;
	} else if (x->o_state == OUTPUTTING) {
		// We're still busy trying to output the last chunk of data, so again
		// we just leave the new data in OT's buffers so flow control will work.
		x->o_datawaiting = 1;
	} else if (x->o_state == GET_NBYTES) {
		// Try to read N bytes
		long numLeftToRead = x->o_numBytesWeWant - x->o_bytesRead;
		if (numLeftToRead <= 0) {
			post("е OTTCP: internal error: read too much.");
		} else {
			oldLockout = AcquireLock(x);
			r = OTRcv(x->o_tcp_ep, x->o_currentReadBuf+x->o_bytesRead, numLeftToRead, &flags);
			ReleaseLock(x,oldLockout);
			if (r == numLeftToRead) {
				// We read everything we wanted, so output the darn buffer
				x->o_bytesRead += r;
				ChangeState(x, OUTPUTTING);
				x->o_whatToOutput = GET_NBYTES;
				clock_delay(x->o_clock, 0);
				// Maybe there's more data to be read
				x->o_datawaiting = 1;	
			} else if (r > 0) {
				// We read some, but not all, of our N bytes.
				x->o_bytesRead += r;
				x->o_datawaiting = 0;
			} else if (r == kOTNoDataErr) {
				// We didn't read squat, but that's supposed to be OK.
				x->o_datawaiting = 0;
			} else if (r == kOTLookErr) {
				OTResult lookr = OTLook(x->o_tcp_ep);
				post("OTTCP: OTRcv returned kOTLookErr; OTLook returned %ld", lookr);
			} else {
				post("е OTTCP: warning: OTRcv returned %ld", r);
			}
		}
	} else if (x->o_state == GET_DELIM) {
		long capacity = x->o_ReadBufSize - x->o_bytesRead;
		long numToRead;
		
		if (capacity > MAX_TO_READ_LOOKING_FOR_DELIMITER) {
			numToRead = MAX_TO_READ_LOOKING_FOR_DELIMITER;
		} else {
			numToRead = capacity;
		}
	readagain:
		oldLockout = AcquireLock(x);
		r = OTRcv(x->o_tcp_ep, x->o_currentReadBuf+x->o_bytesRead, numToRead, &flags);
		ReleaseLock(x,oldLockout);

		if (r == numToRead) {
			// We read everything we asked for
			char *afterDelimiter;
			
			x->o_datawaiting = 1;	// Maybe there's more data to be read
			x->o_bytesRead += r;
			if (FoundDelimiter(x, &afterDelimiter)) {
				ChangeState(x, OUTPUTTING);
				x->o_whatToOutput = GET_DELIM;
				CopyAfterDelimiterToOtherBuffer(x, afterDelimiter);
				clock_delay(x->o_clock, 0);
			} else if (x->o_bytesRead == x->o_ReadBufSize) {
				post("е OTTCP: error: filled %ld byte read buffer but never found delimiter string \"%s\"",
					 x->o_ReadBufSize, x->o_delimiterBytes);
				post("Discarding buffer and calling off the search.  You probably want to reconnect.");
				ChangeState(x, NO_REQUEST);
				x->o_bytesRead = 0;
			} else {
				// We didn't find the delimiter in the MAX_TO_READ_LOOKING_FOR_DELIMITER bytes
				// we read, but we've got more room in our buffer and there may be more
				// data in the OT buffer, so let's do another read.
				goto readagain;
			}
		} else if (r > 0) {
			// We read everything that was available
			char *afterDelimiter;
			x->o_datawaiting = 0;
			x->o_bytesRead += r;
			
			if (FoundDelimiter(x, &afterDelimiter)) {
				ChangeState(x, OUTPUTTING);
				x->o_whatToOutput = GET_DELIM;
				CopyAfterDelimiterToOtherBuffer(x, afterDelimiter);
				clock_delay(x->o_clock, 0);
			} else {
				// We didn't see the delimiter, TCP's buffer is empty, and our buffer
				// still has room, so there's nothing else to do until the next T_DATA event.
			}
		} else if (r == kOTNoDataErr) {
			// We didn't read squat, but that's supposed to be OK.
			x->o_datawaiting = 0;
		} else if (r == kOTLookErr) {
			OTResult lookr = OTLook(x->o_tcp_ep);
			post("OTTCP: OTRcv returned kOTLookErr; OTLook returned %ld", lookr);
		} else {
			post("е OTTCP: warning: OTRcv returned %ld", r);
		}
	} else {
		post("е OTTCP: error: unrecognized state %ld", x->o_state);
	}

bag:
	ExitCallback();
}