www.gusucode.com > 嵌入式linux系统的网络编程源码程序 > 嵌入式linux系统的网络编程源码程序/视频会议源码/network.cpp

    #include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "network.h"


// 发送数据,数据量不定
void send_data( int net_fd, sockaddr_in * addr_accept, BUFF * send_buff,
		const BUFF * data, int size, int & packet_num, packet_type_t packet_type ) // {{{
{

	int pos = 0;
	int remain = size;
	int sub_seq_num = 0;
	packet_head_t * packet_head = new packet_head_t;
	memset( packet_head, 0, sizeof( packet_head_t ) );

	switch ( packet_type )
	{
		// 等待发送的为数据包
		case DATA: // {{{
		{
			// 预置序号
			packet_head->sequence_num = packet_num;
			packet_head->sub_sequence_num = sub_seq_num ;
			packet_head->opt_bits = 0;

			// 刚刚开始,设置开始帧标志和后面继续标志
			SET_AUDIO_BGN_BIT( packet_head->opt_bits );
			SET_AUDIO_CON_BIT( packet_head->opt_bits );

			while ( remain > PACKET_DATA_LENGTH )
			{

				// 当前数据包不是最后一个数据包
				send_line( net_fd, addr_accept, send_buff, data+pos, 
						PACKET_DATA_LENGTH, packet_head ); 

				packet_num++;
				sub_seq_num++;

				// 增加序号
				packet_head->sequence_num = packet_num;
				packet_head->sub_sequence_num = sub_seq_num ;

				// 添加标志
				CLR_AUDIO_BGN_BIT( packet_head->opt_bits );

				remain -= PACKET_DATA_LENGTH;
				pos += PACKET_DATA_LENGTH;

			}

			if ( remain > 0 && remain <= PACKET_DATA_LENGTH )
			{
				// 添加标志
				CLR_AUDIO_CON_BIT( packet_head->opt_bits );
				SET_AUDIO_END_BIT( packet_head->opt_bits );

				send_line( net_fd, addr_accept, send_buff, data+pos, 
						remain, packet_head ); 
				packet_num++;
				sub_seq_num++;
			}

			break;
		} // }}}

		// 等待发送的为SYN包
		case SYN:
		{
			SET_CTRL_SYN_BIT( packet_head->opt_bits );
			send_line( net_fd, addr_accept, send_buff, data, remain, packet_head ); 
			break;
		}

		// 等待发送的为HEARTBEAT包
		case HEARTBEAT:
		{
			SET_CTRL_HEARTBEAT_BIT( packet_head->opt_bits );
			send_line( net_fd, addr_accept, send_buff, data, remain, packet_head ); 
			break;
		}

		// 等待发送的为GOODBYE包
		case GOODBYE:
		{
			SET_CTRL_GOODBYE_BIT( packet_head->opt_bits );
			send_line( net_fd, addr_accept, send_buff, data, remain, packet_head ); 
			break;
		}
	}

	delete packet_head;
	return;

} // }}}


// 发送一个数据包大小,如果数据小于一个数据包则以0补满
int send_line( int net_fd, sockaddr_in * addr_accept, BUFF * send_buff,
		const BUFF * data, int size, packet_head_t * packet_head ) // {{{
{

	int send_size = 0;
	socklen_t acclen;

	acclen = sizeof( *addr_accept );

	// 减缓发送速度,停止10ms
	//msleep( 10 );

	// 判断发送长度
	if ( size == PACKET_DATA_LENGTH )
	{
		// 长度与每个包的数据长度相同,直接发送
		memcpy( send_buff, packet_head, PACKET_HEAD_LENGTH );
		memcpy( send_buff+PACKET_HEAD_LENGTH, data, PACKET_DATA_LENGTH );
	
		send_size = sendto( net_fd, static_cast<void*>( send_buff ), PACKET_LENGTH, 0, 
			(sockaddr*) addr_accept, acclen );
	}
	else
	{

		if ( size < PACKET_DATA_LENGTH )
		{
			// 长度小于每个包的数据长度,先填充
			//memset( send_buff, 0, PACKET_LENGTH );

			memcpy( send_buff, packet_head, PACKET_HEAD_LENGTH );
			memcpy( send_buff+PACKET_HEAD_LENGTH, data, size );
		
			send_size = sendto( net_fd, static_cast<void*>( send_buff ), size + PACKET_HEAD_LENGTH, 0, 
				(sockaddr*) addr_accept, acclen );
		}
		else
		{
			cerr << "Warning! packet data size is larger than expected" << endl;
			return -1;
		}

	}

	return send_size;

} // }}}


// 接收一行数据
int recv_line( int net_fd, sockaddr_in * addr_accept, BUFF * recv_buff,
		BUFF *& data, packet_head_t *& packet_head ) // {{{
{
	int read_size;
	socklen_t acclen;

	acclen = sizeof( *addr_accept );

	read_size = recvfrom( net_fd, static_cast<void*>( recv_buff ), 
			PACKET_LENGTH, 0, (sockaddr*) addr_accept, &acclen );

	data = recv_buff + PACKET_HEAD_LENGTH;

	packet_head = (packet_head_t*) recv_buff;

	return read_size;

} // }}}