【发布时间】:2016-11-30 06:37:55
【问题描述】:
我目前正在用 C++ 为 Linux 编写一个套接字包装器。它基本上是处理 TCP 套接字的创建、连接、发送、读取和关闭的类的集合。
在我的套接字类中,除了发送和接收功能外,所有功能都运行良好。它们不返回错误;相反,它只发送数据的前四个字节。
我的发送功能:
int Socket::sends(char* buffer){
int bytes; // for number of bytes sent
/* First, send the size of buffer */
int datalen = strlen(buffer); // get sizeof buffer
int len = htonl(datalen); // reformat
// send the size of the buffer
bytes = send(socketfd, (char*)&len, sizeof(len), 0); // send the size
if (bytes < 0){
cerr << "Error sending size of buffer to socket" << endl;
return 1;
}
/* Now acutally send the data */
bytes = send(socketfd, buffer, datalen, 0);
if (bytes < 0){
cerr << "Error writing buffer to socket" << endl;
return 1;
}
cout << bytes << " written" << endl;
return 0;
}
其背后的想法是,它发送缓冲区(char* buffer)首先发送缓冲区的大小,然后发送实际的缓冲区。如果遇到错误(返回 -1),则函数通过返回 1 终止。
现在,这里是读取方法:
int Socket::reads(char* buffer){
int bytes, buflen; // for bytes written and size of buffer
/* Read the incoming size */
bytes = recv(socketfd, (char*)&buflen, sizeof(buflen), 0);
if (bytes < 0){
cerr << "Error reading size of data" << endl;
return 1;
}
buflen = ntohl(buflen);
/* Read the data */
bytes = recv(socketfd, buffer, buflen, 0);
if (bytes < 0){
cerr << "Error reading data" << endl;
return 1;
}
return 0;
}
这里的想法是先读取数据的大小,然后将缓冲区设置为该大小并读入。该函数在出错时返回 1(recv 返回 -1)。
使用这些方法看起来像这样:
socket.sends("Hello World"); // socket object sends the message
char* buffer;
socket.reads(buffer); // reads into the buffer
但是,当我使用这些函数时,我只收到前 4 个字节的数据,然后是奇怪的非 ASCII 字符。我不知道为什么会这样。在send 和recv 函数中没有遇到任何错误,并且函数说只写入了4 个字节。有没有更好的方法来发送或接收数据?我忽略了一个非常简单的错误?
感谢您的帮助!
【问题讨论】:
-
请注意,C 和 C++ 是不同的语言。请只使用相关标签。
-
你怎么知道有足够的内存分配给读取?示例代码创建了一个名为
buffer的指针,但没有将它指向任何已分配的内存。 -
如果您使用的是非阻塞套接字,
recv可能会读取包括 0 在内的任意字节数,您需要调用recv直到您获得所有数据或返回错误。跨度> -
int datalen = strlen(buffer); // get sizeof buffer这看起来很可疑 -
char* buffer; socket.reads(buffer);是您的真实代码还是您“简化”了它?