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; } // }}}