什么是从C / C ++ TCP套接字读取正确的方法是什么? [英] What is the correct way of reading from a TCP socket in C/C++?

查看:106
本文介绍了什么是从C / C ++ TCP套接字读取正确的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的code:

// Not all headers are relevant to the code snippet.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <cstdlib>
#include <cstring>
#include <unistd.h>

char *buffer;
stringstream readStream;
bool readData = true;

while (readData)
{
	cout << "Receiving chunk... ";

	// Read a bit at a time, eventually "end" string will be received.
	bzero(buffer, BUFFER_SIZE);
	int readResult = read(socketFileDescriptor, buffer, BUFFER_SIZE);
	if (readResult < 0)
	{
		THROW_VIMRID_EX("Could not read from socket.");
	}

	// Concatenate the received data to the existing data.
	readStream << buffer;

	// Continue reading while end is not found.
	readData = readStream.str().find("end;") == string::npos;

	cout << "Done (length: " << readStream.str().length() << ")" << endl;
}

这是C和C ++,你可以告诉一点点。该BUFFER_SIZE 256 - 我应该只增加大小?如果是这样,什么?有什么关系?

It's a little bit of C and C++ as you can tell. The BUFFER_SIZE is 256 - should I just increase the size? If so, what to? Does it matter?

我知道,如果结束不是什么都接受的理由,这将是一个死循环,这是坏的 - 所以,如果你能提出一个更好的办法,也请这样做。

I know that if "end" is not received for what ever reason, this will be an endless loop, which is bad - so if you could suggest a better way, please also do so.

推荐答案

不知道你的全面应用也很难说解决这个问题的最好办法是什么,但一个共同的技术是使用它与一个启动一个头固定长度字段,表示邮件的其余部分的长度。

Without knowing your full application it is hard to say what the best way to approach the problem is, but a common technique is to use a header which starts with a fixed length field, which denotes the length of the rest of your message.

假设你的头只包含一个4字节的整数,它表示你的消息的其余部分的长度。然后,只需做到以下几点。

Assume that your header consist only of a 4 byte integer which denotes the length of the rest of your message. Then simply do the following.

// This assumes buffer is at least x bytes long,
// and that the socket is blocking.
void ReadXBytes(int socket, unsigned int x, void* buffer)
{
    int bytesRead = 0;
    int result;
    while (bytesRead < x)
    {
        result = read(socket, buffer + bytesRead, x - bytesRead);
        if (result < 1 )
        {
            // Throw your error.
        }

        bytesRead += result;
    }
}

再后来在code

Then later in the code

unsigned int length = 0;
char* buffer = 0;
// we assume that sizeof(length) will return 4 here.
ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length));
buffer = new char[length];
ReadXBytes(socketFileDescriptor, length, (void*)buffer);

// Then process the data as needed.

delete [] buffer;

这使得一些假设:


  • int为对发送器和接收器中的相同的尺寸。

  • 字节序是关于发送者和接收者都相同。

  • 您对双方协议的控制权

  • 当您发送一条消息,就可以计算出长度达阵。

既然是共同想明确地知道你在网络上发送的整数的大小在头文件中定义它们,并明确使用它们,例如:

Since it is common to want to explicitly know the size of the integer you are sending across the network define them in a header file and use them explicitly such as:

// These typedefs will vary across different platforms
// such as linux, win32, OS/X etc, but the idea
// is that a Int8 is always 8 bits, and a UInt32 is always
// 32 bits regardless of the platform you are on.
// These vary from compiler to compiler, so you have to 
// look them up in the compiler documentation.
typedef char Int8;
typedef short int Int16;
typedef int Int32;

typedef unsigned char UInt8;
typedef unsigned short int UInt16;
typedef unsigned int UInt32;

这上面将改变为:

UInt32 length = 0;
char* buffer = 0;

ReadXBytes(socketFileDescriptor, sizeof(length), (void*)(&length));
buffer = new char[length];
ReadXBytes(socketFileDescriptor, length, (void*)buffer);

// process

delete [] buffer;

我希望这有助于。

I hope this helps.

这篇关于什么是从C / C ++ TCP套接字读取正确的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆