使用PHP扩展从PHP连接C套接字服务器
我已经创建了一个PHP扩展来从PHP连接C套接字服务器。我使用以下代码创建了一个PHP扩展:使用PHP扩展从PHP连接C套接字服务器,php,c,sockets,zend-framework,Php,C,Sockets,Zend Framework,我已经创建了一个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(l
#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);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#pragma注释(lib,“Ws2_32.lib”)
#包括
#包括“stdafx.h”
#定义WSA_版本MAKEWORD(2,2)
#定义大小sizeof(结构sockaddr\u in)
#定义SOCKETBUF_尺寸1025
//////////////////////////全球的
int g_iSockfd;
字符g_acRcvData[SOCKETBUF_SIZE];
//////////////////////////类型定义
//typedef无符号短符号;
服务器中的结构sockaddr_;
/*要导出的函数的声明*/
ZEND_功能(连接插座);
/*编译函数列表,以便Zend知道此模块中的内容*/
zend_函数\u条目CustomExtModule_函数[]={
ZEND_FE(连接套接字,空)
{NULL,NULL,NULL}
};
/*编译模块信息*/
zend\u模块\u条目CustomExtModule\u模块\u条目={
标准模块标题,
“自定义文本模块”,
CustomExtModule_函数,
空,空,空,空,空,
还没有版本,标准模块属性
};
/*执行标准的“存根”例程,向Zend自我介绍*/
ZEND_GET_模块(CustomExtModule)
/*连接套接字函数*/
ZEND_函数(连接插座){
char*i_pcIPAddress;
国际i_iPortNumber;
zend_bool return_long=0;
//接收参数
if(zend_parse_参数(zend_NUM_ARGS()TSRMLS_CC,“sd|b”、&i_pcIPAddress、&i_iPortNumber、&return_long)=失败){
RETURN_NULL();
}
//返回字符串(i\u pcIPAddress,1);
int errorcode=0;
WSADATA WSADATA={0};
//服务器。={AF_INET,i_iPortNumber,INADDR_ANY};
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=inet\u addr(i\u pcIPAddress);
server.sin_port=i_iPortNumber;
如果(0!=WSAStartup(WSA_版本和WSAData))
{
//告诉用户我们找不到可用的
//WinSock DLL。
if(LOBYTE(WSAData.wVersion)!=LOBYTE(WSA\u版本)||
HIBYTE(WSAData.wVersion)!=HIBYTE(WSA_版本))
//printf(“发现WS2_32.dll的版本不正确”);
WSACleanup();
errorcode=WSAGetLastError();
返回长(错误代码);
}
//如果相同IP地址和端口的套接字打开,请将其关闭
如果(g_iSockfd!=-1)
{
int nRet=闭合插座(g_iSockfd);
nRet=停堆(g_iSockfd,2);
}
如果((g_iSockfd=socket(AF_INET,SOCK_STREAM,0))==-1{
errorcode=WSAGetLastError();
返回长(错误代码);
}
而(1)
{
if(连接(g_iSockfd,(结构sockaddr*)和服务器,大小)=-1){
errorcode=WSAGetLastError();
返回长(错误代码);
}
返回字符串(“成功”,1);
}
}
我的PHP扩展工作正常
但是,当我试图使用正确的IP地址和端口号调用ConnectSocket函数时,得到的响应是错误代码10061。也就是说,套接字连接已被拒绝
如果我是从direct C客户端代码进行连接,那么我可以成功地建立套接字连接。如果我使用该代码创建PHP扩展,则会出现连接被拒绝错误。
请帮助我解决我的问题。正确地调试代码,您是否可以接收从PHP函数调用传递的C客户端代码中的参数,我希望您不会获得从PHP函数调用传递的参数 检查您的参数接收部分,在那里您必须检查从PHP发送的值的类型是否与C客户端套接字连接脚本中的声明类型相匹配。 我希望用我下面的代码替换接收参数部分,它会工作的
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|b", &i_iPortNumber, &i_pcIPAddress, &return_long) == FAILURE) {
RETURN_NULL();
}
在
if(g_iSockfd!=-1)中首次使用之前,我找不到初始化g_iSockfd
的地方。
我已经在全局变量声明部分声明了这个g_iSockfd变量,无论如何,我正在检查它是否是!=-1然后我关闭插座连接,然后连接插座。(正在创建套接字,但未连接)