1.Qt
变量说明:
char msg : 用于存储从socket读取的数据
head.length:这个变量也是右socket传过来,第一次先传长度(或包含长度的结构体)
int recvNum:用于存储read socket数据的实际长度;
(QTcpSocket mp_qTcpSocket; ->这个是指用于通讯的socket)
char* msg = new char[head.length];
int remainLen = head.length;//记录总长度,以及之后未读数据的长度
int recvNum = 0;//用于记录read实际从缓冲区读取到的数据长度
int offset = 0;//read读取数据后内存地址的指向的位置
while (remainLen > 0) {
//msg+offset指的是内存中指针的位置,第一次从0开始,之后每次都从上次读取数据总长度后面继续读取数据
recvNum = mp_qTcpSocket->read(msg + offset, remainLen);
if (recvNum == -1) {
//断开socket连接(判断errno,socket不可用需要重新断开重连)
tcp_disconnect();
} else if (recvNum == 0) {
//对端的连接断开,继续等待其他socket连接
qDebug() << "recvNum == 0" << endl;
continue;
} else {
//正常接收数据,返回从缓冲区读取到的数据
//未读取数据长度 = 之前socket收到的数据总长度 - 本次实际从缓冲区读取到的数据长度
remainLen = remainLen - recvNum;
//跟新已经读取了数据的位置
offset = offset + recvNum;
}
}
2.C++
ssize_t Client::readData(int fd, void* userbuf, size_t length)
{
//socket数据的总长度
size_t nleft = length;
//下面while循环中每次实际读取到的数据长度
ssize_t nread = 0;
//存储数据
char* bufp = (char*)userbuf;
while (nleft > 0) {
std::cout<<“nleft:”<<nleft<<std::endl;
nread = read(fd, bufp, nleft);
if (nread < 0) {
std::cout<< "read error: " << strerror(errno) << std::endl;
if (errno == EINTR) {
nread = 0;
} else {
return -1;
}
} else if (nread == 0) {
break; // EOF
}
//成功从缓冲区读取数据
nleft -= nread; //剩下未读取数据长度 = 总数据长度 - 本次读取数据长度
bufp += nread; //存储数据内存指针往后移动读取到的数据长度,以便下次读取从未读取数据的内存地址开始读取数据
}
//返回数据的长度
return length - nleft;
}
用法:
int len = 0;
static char gbuffer[819600] = {0};
memset(gbuffer, 0, sizeof(gbuffer));
=================================================================
//先读取数据长度,再读取数据
uint32_t msg_length = 0;
len = readData(sockfd, &msg_length, sizeof(uint32_t));//与socket另一端配合,先读取数据长度(另一端也要同步先发送数据长度)
=================================================================
//先读取一个结构体,再读取数据(结构体中需要包含长度,其他的值可以自行定义)
typedef struct dataT{
int data_id;
unsigned long time_stamp;
int buffer_size;
}qdataT_t;
qdataT_t m_recvData;
memset(&m_recvData, 0 , sizeof(m_recvData));
readData(socket_fd,&m_recvData,androdHeadLen);
auto error = readData(android_fd,img_buf,m_recvData.buffer_size);
if (error < 0)
{
std::cout << strerror(error);
continue;
}
=================================================================
if (len > 0)
{
int nread = readData(sockfd, gbuffer, msg_length);//将数据读取到gbuffer数组中
//正常读取数据后的处理
。。。。
}
else if (len == 0)
{
//另一端的客户端断开连接
std::cout<<“server socket close”<<std::endl;
//等待其他socket连接
continue;
}
else if (len = -1)
{
//本身socket出现问题,必须重启
}