예제 #1
0
파일: Xrecv.c 프로젝트: BigQNo2/xia-core
/*!
** @brief Receive data from an Xsocket
**
** Xrecv() retrieves data from a connected Xsocket of type XSOCK_STREAM.
** sockfd must have previously been connected via Xaccept() or
** Xconnect().
**
** Xrecv() does not currently have a non-blocking mode, and will block
** until a data is available on sockfd. However, the standard socket API
** calls select and poll may be used with the Xsocket. Either function
** will deliver a readable event when a new connection is attempted and
** you may then call Xrecv() to get the data.
**
** NOTE: in cases where more data is received than specified by the caller,
** the excess data will be stored at the API level. Subsequent Xrecv calls
** return the stored data until it is drained, and will then resume requesting
** data from the transport.
**
** @param sockfd The socket to receive with
** @param rbuf where to put the received data
** @param len maximum amount of data to receive. the amount of data
** returned may be less than len bytes.
** @param flags (This is not currently used but is kept to be compatible
** with the standard sendto socket call).
**
** @returns the number of bytes received, which may be less than the number
** requested by the caller
** @returns -1 on failure with errno set to an error compatible with the standard
** recv call.
*/
int Xrecv(int sockfd, void *rbuf, size_t len, int flags)
{
	int numbytes;
	char UDPbuf[MAXBUFLEN];
	
	if (flags) {
		errno = EOPNOTSUPP;
		return -1;
	}

	if (len == 0)
		return 0;

	if (!rbuf) {
		LOG("buffer pointer is null!\n");
		errno = EFAULT;
		return -1;
	}

	if (validateSocket(sockfd, XSOCK_STREAM, EOPNOTSUPP) < 0) {
		LOGF("Socket %d must be a stream socket", sockfd);
		return -1;
	}

	if (!isConnected(sockfd)) {
		LOGF("Socket %d is not connected", sockfd);
		errno = ENOTCONN;
		return -1;
	}

	// see if we have bytes leftover from a previous Xrecv call
	if ((numbytes = getSocketData(sockfd, (char *)rbuf, len)) > 0)
		return numbytes;

	if ((numbytes = click_reply(sockfd, UDPbuf, sizeof(UDPbuf))) < 0) {
		LOGF("Error retrieving recv data from Click: %s", strerror(errno));
		return -1;
	}

	std::string str(UDPbuf, numbytes);
	xia::XSocketMsg xsm;

	xsm.ParseFromString(str);

	xia::X_Recv_Msg *msg = xsm.mutable_x_recv();
	unsigned paylen = msg->payload().size();
	const char *payload = msg->payload().c_str();

	if (paylen <= len)
		memcpy(rbuf, payload, paylen);
	else {
		// we got back more data than the caller requested
		// stash the extra away for subsequent Xrecv calls
		memcpy(rbuf, payload, len);
		paylen -= len;
		setSocketData(sockfd, payload + len, paylen);
		paylen = len;
	}
	return paylen;
}
예제 #2
0
bool Converter::setSocketDataFromElement(SocketData* socketData,
		TiXmlElement* ele, const string key) {
	TiXmlElement* el = ele->FirstChildElement(key.c_str());
	if (el == NULL)
		return false;

	//printf("%s\n",key.c_str());

	const char* keyc = NULL;
	const string* tagList = NULL;
	int tagListSize = 0;
	if (key == TAG_EXECDATA) {
		setSocketDataFromClass(socketData, el, key, execTagList,
				execTagListSize);
	} else if (key == TAG_FUNCLIST) {
		keyc = TAG_FUNCDATA;
		tagList = funcTagList;
		tagListSize = funcTagListSize;
		/*TODO resize */
		if(mFuncNum != 0){
			socketData->getExecData()->getKernelCode(mKernelListIndex)->getFuncDataList()->resize(mFuncNum);
			for (TiXmlElement* el2 = el->FirstChildElement(keyc); el2 != NULL;
					el2 = el2->NextSiblingElement(keyc)) {
	//			socketData->getExecData()->addFuncData();
				mFuncListIndex++;
				for (int i = 0; i < tagListSize; i++) {
					setSocketDataFromElement(socketData, el2, tagList[i]);
				}
			}
			mFuncListIndex = -1;
		}else{
			printf("Parse Error : please <funcnum> parameter!\n");
			return false;
		}
	} else if (key == TAG_RESOURCESIZE){
		mIsResSize = FLAG_DEVICE_CURRENT;
		setSocketDataFromClass(socketData, el, key, resSizeTagList,
				resSizeTagListSize);
	} else if( key == TAG_RESOURCESIZE_SELECTED) {
		mIsResSize = FLAG_DEVICE_SELECTED;
		setSocketDataFromClass(socketData, el, key, resSizeTagList,
				resSizeTagListSize);
	} else if (key == TAG_GLOBALWORKSIZE || key == TAG_LOCALWORKSIZE) {
		if(key == TAG_GLOBALWORKSIZE) mIsGws = FLAG_GLOBALWORKSIZE;
		else if (key == TAG_LOCALWORKSIZE) mIsGws = FLAG_LOCALWORKSIZE;
		keyc = TAG_WORKSIZE;
		tagList = workItemSizeTagList;
		tagListSize = workItemSizeTagListSize;
		for (TiXmlElement* el2 = el->FirstChildElement(keyc); el2 != NULL;
				el2 = el2->NextSiblingElement(keyc)) {
			//printf("%s : %s\n",keyc, el2->GetText());
			setSocketData(socketData, keyc,el2->GetText());
		}
	} else if (key == TAG_KERNELLIST) {
		keyc = TAG_KERNEL;
		tagList = kernelTagList;
		tagListSize = kernelTagListSize;
		/*TODO resize */
		if(mKernelNum != 0){
			socketData->getExecData()->getKernelCodeList()->resize(mKernelNum);
			for (TiXmlElement* el2 = el->FirstChildElement(keyc); el2 != NULL;
					el2 = el2->NextSiblingElement(keyc)) {
				//socketData->getExecData()->addKernelCode();
				mKernelListIndex++;
				for (int i = 0; i < tagListSize; i++) {
					setSocketDataFromElement(socketData, el2, tagList[i]);
				}
			}
			mKernelListIndex = -1;
		}else{
			printf("Parse Error : please <kernelnum> parameter!\n");
			return false;
		}
	} else {
		setSocketData(socketData, key, el->GetText());
	}
	return true;
}