我查看了这里的过去的线程,找到有关C套接字被翻译成PHP套接字的任何相关主题,我已经准备好在php.net和C教程上进行了广泛的研究,以找出如何将一些C源代码转换为涉及远程套接字连接的PHP源代码。
我要发布的源代码是C.这段代码已经工作并确认可以在我编程的一个程序员编写的.exe中工作。他不知道PHP,我正在创建这个新程序,需要这个片段。
程序执行此操作:它创建到远程服务器/端口的套接字连接,发送它需要发送到服务器的图像的文件大小,然后我猜测服务器何时知道文件大小,程序发送二进制图像数据和图像的文件大小(如通过套接字上传到服务器的功能)。然后它使用recv(); C中的函数用于接收特定长度的字节。
基本上它正在发送带有加密内容的图片。服务器已在指定端口上运行正在解密映像的程序。然后套接字正在发回该解密文本。我没有访问解密算法,否则我不会明显使用套接字。
以下是我发送的C源代码,以及我后来尝试使用PHP正确翻译它。
//在这个C代码中,有很长的大小;在底部使用但从未初始化的变量。我不知道该怎么做。其他一些变量也从未使用过。
function picBin() assume curlBinaryData variable pic is filled with binary data from picture download. pic->currentSize is set to the size of the image
如果成功,它将返回0。函数的参数中的char *字也将被设置为pic的解密
// bin数据结构我用于快速的ghetto下载功能,只是让你知道它看起来如何
struct curlBinaryData{
char *data;
int currentSize;
int maxSize;
};
int picBin(curlBinaryData *pic, char *word, int threadNum,
char *host, unsigned short port)
{
char data1[1000], data2[1000],
temp[1000], printBuf[1000], buffer[1000], *p, *p2;
int num, a, totalBytes;
long size;
char *pSize;
SOCKET sock;
while ((sock = connectSocket(host, port)) == INVALID_SOCKET)
{
sprintf(printBuf, "Could not connect(picBin) %s:%d\n", host, port);
print_ts(printBuf, "red");
//Sleep(15000);
}
buffer[0]='\0';
send(sock, buffer, 1, 0);
pSize=(char *)&(pic->currentSize);
send(sock, pSize, 4, 0);
send(sock, pic->data, pic->currentSize, 0);
totalBytes=0;
do{
if ( (num=recv(sock, data1+totalBytes, 1, 0)) > 0)
totalBytes+=num;
} while( (totalBytes<4) && (num>0) );
pSize=(char *)&size;
if (totalBytes==4){ //got 4 bytes for dword
memcpy(pSize, data1, 4);
if (size==1)
{
totalBytes=0;
do
{
if ( (num=recv(sock, data1+totalBytes, 1, 0)) > 0)
totalBytes+=num;
} while( (totalBytes<4) && (num>0) );
memcpy(pSize, data1, 4);
if (totalBytes==4)
{ //got 4 bytes for dword
totalBytes=0;
for (a=0; ( (a<size) && (num>0) ); a++)
{
if ( (num=recv(sock, data1+totalBytes, 1, 0)) > 0)
totalBytes+=num;
}
if (totalBytes==size)
{
closesocket(sock);
data1[totalBytes]='\0';
strcpy(word, data1);
return 0; //0 on success
}
}
}
}
closesocket(sock);
return -1; //something errord
}
现在这是我尝试的PHP代码:
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false)
{
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_connect($sock, $host, $port) === false)
{
echo "socket_connect() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
socket_send($sock, '\0', 1, MSG_EOF);
$ci = file_get_contents($picURL);
$ciwrite = fopen('pic.jpg', 'w+');
fwrite($ciwrite, $ci);
fclose($ciwrite);
$picFileSize = filesize('pic.jpg');
socket_send($sock, $picFileSize, 4, MSG_EOF);
socket_send($sock, $ci, $picFileSize, MSG_EOF);
$num = socket_recv($sock, $totalBytes, 1, MSG_DONTWAIT);
print $num; // this doesn't even Print anything to my console when I execute it via CLI
/*do{
if (($num = socket_recv($sock, $totalBytes, 1)) > 0)
{
$totalBytes += $num;
}
} while(($totalBytes < 4) && ($num > 0));*/
答案 0 :(得分:0)
buffer[0]='\0'; send(sock, buffer, 1, 0);
socket_send($sock, '\0', 1, MSG_EOF);
\'
和\\
以外的反斜杠转义序列不会在单引号字符串中展开;因此,'\0'
是两个字符\
和0
的字符串,上面的socket_send()
发送字符\
。
MSG_EOF
充其量只是没有效果,最坏的是有害的;最好不要使用它。
正确的翻译是:
socket_send($sock, "\0", 1, 0);
pSize=(char *)&(pic->currentSize); send(sock, pSize, 4, 0);
socket_send($sock, $picFileSize, 4, MSG_EOF);
以上socket_send()
发送$picFileSize
的ASCII字符串表示的前4个字符,因为socket_send()
期望字符串作为其第二个参数,因此给定整数被强制转换为字符串。发送一个4字节的二进制整数:
socket_send($sock, pack("L", $picFileSize), 4, 0);
$num = socket_recv($sock, $totalBytes, 1, MSG_DONTWAIT); print $num; // this doesn't even Print anything to my console when I execute it via CLI
如果你 DONTWAIT ,你也不会得到任何数据。
C程序接收部分的工作翻译是:
$totalBytes = socket_recv($sock, $data1, 4, MSG_WAITALL);
if ($totalBytes==4)
{ //got 4 bytes for dword
$size = unpack("L", $data1);
if ($size[1]==1)
{
$totalBytes = socket_recv($sock, $data1, 4, MSG_WAITALL);
if ($totalBytes==4)
{ //got 4 bytes for dword
$size = unpack("L", $data1);
$totalBytes = socket_recv($sock, $data1, $size[1], MSG_WAITALL);
if ($totalBytes==$size[1])
{
echo $data1, "\n";
}
}
}
}
答案 1 :(得分:-1)
关于C套接字被转换为PHP套接字
套接字由操作系统实现 - 而不是语言。没有C套接字和PHP套接字。
当你从PHP调用socket_send时,它会将消息转换为字符串(如果它不是一个字符串)。
pSize=(char *)&(pic->currentSize);
send(sock, pSize, 4, 0);
WTF?假设pic-&gt; currentSize包含一个字符串表示,如果图像为什么硬编码为4个字节!
但是在这里:
send(sock, pic->data, pic->currentSize, 0);
pic-&gt; currentSize必须包含整数值。在指向整数(或长,因为看起来是'大小'的声明)的指针前面推(char *)不要让它成为一个字符串。它仍然是一个指针。 OK一个32位指针将是4个字节 - 但WTF是一个通过套接字发送的指针???除非这里有一些奇怪的重载,这实际上是C ++而不是C。
进一步读取它会将指针发送到远程端,然后读回一个4字节的值,如果它与指针匹配则认为操作成功.... !! AAARRGGHHH!即使是发送大小,这种级别的完整性检查在Unix或INET套接字上完全是多余的。
我会挖掘更多,但这会浪费时间来理解这个C代码。使用网络嗅探器来计算出真正发生的事情;不要将此C代码用作如何编写自己的客户端的任何模型。