php - 使用 PHP 扩展从 PHP 连接 C 套接字服务器

标签 php c sockets zend-framework

我创建了一个 PHP 扩展来从 PHP 连接 C Socket 服务器。我使用以下代码创建了一个 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 作为响应。这意味着,Socket 连接已被拒绝。

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

请帮我解决我的问题。

最佳答案

正确调试您的代码,您的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();
      }

关于php - 使用 PHP 扩展从 PHP 连接 C 套接字服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18209827/

相关文章:

php - Jenkins(使用Ant)未执行PHPUnit测试

php - 如何找出使用 PHPExcel 从 Excel 文件中读取的行数和列数?

c++ - 如何使用 OpenSSL 1.1.0 验证主机名?

c - Valgrind 内存泄漏这是什么错误?

java - 需要双重输入。为什么?

php - Laravel 4:Input::has() + Input::get() vs. ($var = Input::get()) != null

php - 我的 PDO 函数出错

c++ - 同一系统上的两个版本的 glibc

java - 如何使用Socket的输入流处理来自浏览器的HTTPS get请求

gethostbyname() 可以返回 IPv6 地址吗?