我正在尝试开发一个函数,用于以正确格式的websocket数据发送来编码文本。这是PHP中的一个函数,但我不能用C语言翻译它。
private function encode($text) {
// 0x1 text frame (FIN + opcode)
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCS', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCN', $b1, 127, $length);
return $header.$text;
}
答案 0 :(得分:1)
对官僚机构的需求较少,因此实施起来要简单得多。通常,您希望调用者提供输出缓冲区和文本大小,所以让我们这样做。
另外,要特别注意字节顺序,第二次使用pack
时,PHP代码应该使用'CCn'
而不是'CCS'
。
示例实施:
static char *hdr_fill(char *buf, unsigned int hlen, size_t plen)
{
*buf++ = 0x81; /* b1 */
switch (hlen) {
case 6:
*buf++ = 127;
break;
case 4:
*buf++ = 126;
}
/* Store length in big endian order */
switch (hlen) {
case 6:
*buf++ = plen >> 24;
*buf++ = plen >> 16;
case 4:
*buf++ = plen >> 8;
case 2:
*buf++ = plen;
}
return buf;
}
size_t encode(char *buf, size_t bufsize, const char *text, size_t len)
{
const unsigned int hdrlen = len > 65535 ? 6 : (len > 255 ? 4 : 2);
if (bufsize < hdrlen + len)
return 0;
buf = hdr_fill(buf, hdrlen, len);
memcpy(buf, text, len);
return hdrlen + len;
}
为方便起见,它返回结果的大小。您至少需要<stddef.h>
(除非您替换size_t
)和<string.h>
。
但是,您可能希望使用分散 - 聚集方法,因为它避免了复制。在这种情况下,您只需要构建标题并调整它的向量。此外,IMO更优雅:
int setup_header(struct iovec *v, int n)
{
/* We expect a valid buffer in v[0], and the payload in v[1+] */
if (n < 2 || v[0]->iov_len < 6)
return -1;
size_t len = v[1]->iov_len;
for (int i = 2; i < n; i++)
len += v[n]->iov_len;
const unsigned int hdrlen = len > 65535 ? 6 : (len > 255 ? 4 : 2);
v[0]->iov_len = hdrlen;
hdr_fill(v[0]->iov_base, hdrlen, len);
return 0;
}
在这种情况下,如果成功,返回值为零。对于这个,你需要<sys/uio.h>
或同等的。