Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android RakNet 系列之四 實現消息、語音、文件傳輸

Android RakNet 系列之四 實現消息、語音、文件傳輸

編輯:關於Android編程

簡介

RakNet在Win平台上已經實現消息、語音、文件傳輸了,但在Android平台下尚未實現,筆者決定把源碼移植到Android平台下測試。

詳情

實現消息

項目自帶Chat Example Client和Chat Example Server實現消息,源碼簡單易懂,此處就不介紹了,直接貼上圖片。

vcq9z9TKvrXEo6zNvMaszrSytte9tb3P1Mq+oaM8L3A+PGg1Psq1z9bT79L0PC9oNT48cD5XaW7Gvcyoz8LKtc/W0+/S9MrHzai5/VBvcnRhdWRpb7340NC1xKOsUG9ydGF1ZGlvydDOtNans9ZBbmRyb2lko6zSqsq1z9bT79L01PXDtLDso788L3A+PHA+SmF2YbLjyrXP1r/J0tSjrLWrscrV3771tcPC6bezo6y+9rao0sbWslBvcnRhdWRpb7W9QW5kcm9pZKGjudjT2tXit73D5rXE0MXPosfrsum/tLKpv82jukFuZHJvaWQgUmFrTmV0IM+1wdDWrsj9INLG1rJQb3J0YXVkaW+hozwvcD48cD7Ktc/W1K3A7aO6UmFrbmV0zai5/VBvcnRBdWRpb7340NDT79L0ssm8r9LUvLCypbfFo6zU2c2ouf1SYWtWb2ljZdPv0vSy5bz+vfjQ0NPv0vS3osvN0+u908rco6xSYWtWb2ljZdbQyrnTw8HLc3BlZXix4MLrtKvK5KGjPC9wPjxwPkpuacq1z9bW99KqtPrC68jnz8KjujwvcD48cD48L3A+PHByZSBjbGFzcz0="brush:java;">class Voice { //聲音一個操作語音的類 public: Voice(); virtual ~Voice(); void run(const char* ip); //關鍵執行 int portInAudioCallback(const void *inputBuffer); int portOutAudioCallback(void *inputBuffer); void waitForStop(); void stop(); public: bool mute; RakNet::RakPeerInterface *rakPeer; RakNet::RakVoice rakVoice; PaError err; bool isStoped; bool runState; };

void Voice::run(const char* ip) { //通過Ip連接對方機子,然後傳輸。
	////////////////////////////////////////////
	if (err != paNoError) {
		LOGI("Pa_Initialize fail: %s",Pa_GetErrorText(err));
		return;
	}

	mute = false;

	PaStream *stream;

	unsigned int maxConnectionsAllowed = 4;
	unsigned int maxPlayersPerServer = 4;
	unsigned short serverPort = 6000;

	RakNet::SocketDescriptor socketDescriptor(serverPort, 0);

	if (rakPeer->Startup(maxConnectionsAllowed, &socketDescriptor, 1) != RakNet::RAKNET_STARTED) {
		LOGI("Startup fail:");
		return;
	}

	rakPeer->SetMaximumIncomingConnections(maxPlayersPerServer);

	rakPeer->AttachPlugin(&rakVoice);
	rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER * sizeof (short));

	PaDeviceIndex numdev;
	const PaDeviceInfo *info;
	int i;

	numdev = Pa_GetDeviceCount();

	PaStreamParameters inparam, outparam;
	memset(&inparam, 0, sizeof (PaStreamParameters));

	inparam.device = Pa_GetDefaultInputDevice();
	inparam.channelCount = 1;
	inparam.sampleFormat = paInt16;

	memset(&outparam, 0, sizeof (PaStreamParameters));

	outparam.device = Pa_GetDefaultOutputDevice();
	outparam.channelCount = 1;
	outparam.sampleFormat = paInt16;

	PaError err = Pa_OpenStream(&stream,
		&inparam,
		&outparam, 
		SAMPLE_RATE, 
		FRAMES_PER_BUFFER,
		paClipOff,
		PAInOutCallback,
		this);
	err = Pa_SetStreamFinishedCallback(stream, &StreamFinished );
	if(err != paNoError){
		LOGI("Cannot set stream finish callback");
		return;
	}

	if (err != paNoError) {
		LOGI("Pa_OpenStream fail: %s",Pa_GetErrorText(err));
		return;
	}

	err = Pa_StartStream(stream);

	if (err != paNoError) {
		LOGI("Pa_StartStream fail: %s",Pa_GetErrorText(err));
		return;
	}

	if (ip) {
		LOGI("Connect: %s",ip);
		rakPeer->Connect(ip, serverPort, 0, 0);
	}

	RakNet::Packet *p;
	unsigned char typeId;
	isStoped = false;
	runState = true;
	while (1) {
		if(!runState)
		{
			Pa_AbortStream(stream);
			Pa_CloseStream(stream);
			isStoped = true;
			return;
		}

		p=rakPeer->Receive();
		while (p)
		{
			LOGI("Receive data from: %s   guid",p->systemAddress.ToString(),p->guid.ToString());

			if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
			{
					LOGI("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString());
					rakVoice.RequestVoiceChannel(p->guid);
			}
			else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
			{
					LOGI("ID_CONNECTION_ATTEMPT_FAILED\n");
			}
			else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY)
			{
				LOGI("Got new channel from %s\n", p->systemAddress.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				LOGI("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				LOGI("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				LOGI("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS)
			{
				RakNet::RakNetGUID g;
				RakNet::BitStream b(p->data, p->length, false);
				b.IgnoreBits(8); // Ignore the ID_...
				b.Read(g);
				LOGI("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED)
			{
				LOGI("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString());
			}
			else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED)
			{
				LOGI("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString());
				rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0);
			}
			else if (p->data[0]==ID_ALREADY_CONNECTED)
			{
				LOGI("ID_ALREADY_CONNECTED\n");
			}
			else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL)
			{
				LOGI("ID_RAKVOICE_CLOSE_CHANNEL\n");
			}
			else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
			{
				LOGI("ID_DISCONNECTION_NOTIFICATION\n");
			}
			else if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
			{
				LOGI("ID_NEW_INCOMING_CONNECTION\n");
			}
			else if(p->data[0]==ID_CONNECTION_LOST)
			{
				LOGI("ID_CONNECTION_LOST 可靠的數據包不能被傳遞到指定的分組系統");
			}
			else
			{
				LOGI("Unknown packet ID %i\n", p->data[0]);
			}

			rakPeer->DeallocatePacket(p);
			p=rakPeer->Receive();
		}


		Pa_Sleep( 30 );
	}
}

效果如圖:

\

實現文件傳輸
Win平台下的文件傳輸Demo直接移植到Android平台便可實現,代碼如下:

class CBTransferInterface : public RakNet::FileListTransferCBInterface //傳輸文件接口
{
public:
	 bool OnFile(OnFileStruct *onFileStruct);
	virtual void OnFileProgress(FileProgressStruct *fps);
	virtual bool OnDownloadComplete(DownloadCompleteStruct *dcs);
};

// Sender progress notification
class TestFileListProgress : public RakNet::FileListProgress //進度通知
{
	virtual void OnFilePush(const char *fileName, unsigned int fileLengthBytes, unsigned int offset, unsigned int bytesBeingSent, bool done, RakNet::SystemAddress targetSystem, unsigned short setID);
	virtual void OnFilePushesComplete( RakNet::SystemAddress systemAddress, unsigned short setID );
	virtual void OnSendAborted( RakNet::SystemAddress systemAddress );

};

class FileTransferClient //客戶端
{
public:
	int testTransfer(const char* ip,const char* filePath);
	void stopTransfer();
	void waitForStop();
public:
	int transferStatus;
	int isStoped;
};

效果如圖:



結束

至此,在Android平台下已經實現了消息、語音、文件傳輸等功能,近期將實現視頻。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved