0

我创建了一个 PHP 扩展来从 PHP 连接一个 C 套接字服务器。我使用以下代码创建了一个 PHP 扩展:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <WinSock.h>
    #pragma comment(lib, "Ws2_32.lib")
    #include <windows.h>
    #include "stdafx.h"
    #define WSA_VERSION  MAKEWORD(2,2)
    #define SIZE sizeof(struct sockaddr_in)
    #define SOCKETBUF_SIZE 1025

    ////////////////////////// Globals
    int g_iSockfd;
    char g_acRcvData[SOCKETBUF_SIZE];

    ////////////////////////// type defines 
    //typedef unsigned short ssize_t;
    struct sockaddr_in server;


    /* declaration of functions to be exported */
    ZEND_FUNCTION(ConnectSocket);

    /* compiled function list so Zend knows what's in this module */
    zend_function_entry CustomExtModule_functions[] = {
        ZEND_FE(ConnectSocket, NULL)
        {NULL, NULL, NULL}
    };

    /* compiled module information */
    zend_module_entry CustomExtModule_module_entry = {
        STANDARD_MODULE_HEADER,
        "CustomExt Module",
        CustomExtModule_functions,
        NULL, NULL, NULL, NULL, NULL,
        NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
    };

    /* implement standard "stub" routine to introduce ourselves to Zend */
    ZEND_GET_MODULE(CustomExtModule)

    /* ConnectSocket function */
    ZEND_FUNCTION(ConnectSocket){
        char* i_pcIPAddress; 
        int i_iPortNumber;
        zend_bool return_long = 0;
                    // Receiving parameters
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sd|b", &i_pcIPAddress, &i_iPortNumber, &return_long) == FAILURE) {
             RETURN_NULL();
        }
        //RETURN_STRING(i_pcIPAddress,1);
        int errorcode=0;
        WSADATA     WSAData = { 0 };

        //server. = {AF_INET, i_iPortNumber, INADDR_ANY};
        server.sin_family=AF_INET;
        server.sin_addr.s_addr = inet_addr(i_pcIPAddress);
        server.sin_port = i_iPortNumber;


        if ( 0 != WSAStartup( WSA_VERSION, &WSAData ) )
        {
            // Tell the user that we could not find a usable
            // WinSock DLL.
            if ( LOBYTE( WSAData.wVersion ) != LOBYTE(WSA_VERSION) ||
                 HIBYTE( WSAData.wVersion ) != HIBYTE(WSA_VERSION) )
                //printf("Incorrect version of WS2_32.dll found");

            WSACleanup( );
            errorcode = WSAGetLastError();
            RETURN_LONG(errorcode);
        }

        // close socket of same ipaddress and port if its open 
        if(g_iSockfd != -1)
        {
            int nRet = closesocket( g_iSockfd );
            nRet=shutdown(g_iSockfd,2);
        }
        if((g_iSockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {       
            errorcode = WSAGetLastError();
            RETURN_LONG(errorcode);
        }

        while( 1 )
        {
            if(connect(g_iSockfd, (struct sockaddr *)&server, SIZE) == -1) {
                errorcode = WSAGetLastError();
                RETURN_LONG(errorcode);
            }
            RETURN_STRING("Success",1);
        }   


    }

我的 PHP 扩展工作正常。

但是当我尝试使用正确的 IP 地址和端口号调用 ConnectSocket 函数时,我收到错误代码10061作为响应。这意味着,套接字连接已被拒绝。

如果我从直接 C 客户端代码连接,那时我可以成功建立套接字连接。如果我使用该代码创建 PHP 扩展,则会收到 Connection denied 错误。

请帮我解决我的问题。

4

1 回答 1

0

正确调试你的代码,你能否在你的 C 客户端代码中接收到 PHP 函数调用传递的参数,我希望你不会得到你从 PHP 函数调用传递的参数。

检查您的参数接收部分,您必须检查从 PHP 发送的值的类型应该与您的 C 客户端套接字连接脚本中的声明类型相匹配。

我希望用我的以下代码替换您的接收参数部分,它会起作用。

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|b", &i_iPortNumber, &i_pcIPAddress,  &return_long) == FAILURE) {
          RETURN_NULL();
      }
于 2013-08-16T08:16:09.163 回答