doutangguan2460 2011-06-06 05:17
浏览 35

翻译代码:C套接字到PHP套接字

I looked through past threads on here to find any relevant topics regarding C sockets being translated to PHP sockets, and I've ready extensively on php.net and C tutorials to figure out how to convert some C source code I have into PHP source code involving a remote socket connection.

The source I am going to post is in C. This code is already working and confirmed to work in a compiled .exe that one of my programmers wrote. He doesn't know PHP, which I am creating this new program in that requires this snippet.

The program does this: It creates a socket connection to a remote server/port, sends the filesize of an image that it needs to send to the server, then I am guessing when the server knows the filesize, the program sends the binary image data and the filesize of the image again (like an upload feature to the server via sockets). Then it uses the recv(); function in C to receive the bytes back of a specific length.

Basically it is sending a picture with something encrypted inside of it. The server already has a program running on it on the specified port that is decrypting the image. Then the socket is sending back that decrypted text. I do not have access to the algorithm for decryption otherwise I would not be using sockets obviously.

Here is the C source I was sent, and my subsequent attempts in PHP to translate it properly.

// In the this C code, there is the long size; variable that is used at the bottom but is never initialized. I don't know what to do with it. Some other variables are never used either.

function picBin()
assume curlBinaryData variable pic is filled with binary data from picture download.
pic->currentSize is set to the size of the image

it will return 0 if successful. also char *word in the function's params will be set to the pic's decryption

//bin data structure i use for a quick ghetto download function, just so you know how it looks

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
", 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
}

Now here is my PHP code I attempted:

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false)
{
  echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "
";
}

if (socket_connect($sock, $host, $port) === false)
{
  echo "socket_connect() failed: reason: " . socket_strerror(socket_last_error($sock)) . "
";
}

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 &lt; 4) && ($num > 0));*/
  • 写回答

2条回答 默认 最新

  • douyi1197 2011-06-06 09:03
    关注

    regarding C sockets being translated to PHP sockets

    Sockets are implemented by the OS - not the language. There is no such thing as a C socket nor a PHP socket.

    When you invoke socket_send from PHP it converts the message to a string (if it's not already one).

    pSize=(char *)&(pic->currentSize);
    send(sock, pSize, 4, 0);
    

    WTF? Assuming that pic->currentSize contains a string represenation if the image why is it hard coded to 4 bytes!

    But here:

    send(sock, pic->data, pic->currentSize, 0);
    

    pic->currentSize must contain an integer value. Shoving (char *) in front of a pointer to an integer (or a long, since that appears to be how 'size' is declared) DOES NOT MAKE IT a string. It's still a pointer. OK a 32 bit pointer will be 4 bytes - but WTF is a pointer being sent over a socket??? Unless there's some weird overloading going on here and this is actually C++ rather than C.

    Reading further on it sends the pointer to the remote end then reads back a 4 byte value and considers the operation successful if it matches the pointer....!! AAARRGGHHH! even if it were sending the size, this level of integrity checking is entirely redundant over a Unix or INET socket.

    I'd dig some more but it's going to be a waste of time trying to make sense of this C code. Use a network sniffer to work out what's really happenning here; do not use this C code as any sort of model of how to write your own client.

    评论

报告相同问题?

悬赏问题

  • ¥15 用三极管设计一个单管共射放大电路
  • ¥20 fluent无法启动
  • ¥15 孟德尔随机化r语言运行问题
  • ¥15 pyinstaller编译的时候出现No module named 'imp'
  • ¥15 nirs_kit中打码怎么看(打码文件是csv格式)
  • ¥15 怎么把多于硬盘空间放到根目录下
  • ¥15 Matlab问题解答有两个问题
  • ¥15 LCD12864中文显示
  • ¥15 在使用CH341SER.EXE时不小心把所有驱动文件删除了怎么解决
  • ¥15 gsoap生成onvif框架