PHP中的socket连接问题? 我的Apache服务器是运行在windows下面的,浏览器是IE6,而且已经把php_sockets.dll和php_w32api.dll加载了,我的server程序用自己的测试程序连接都是可以的,不知道为什么在php中就不行了,哪位大虾能说说 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在socket_connect之后,调用socket_strerror(socket_last_error()) 得到的结果是“操作成功完成”,真是奇怪了 用了fsockopen,结果是一样的 我用的是Foxserv,是不是配置上有什么需要注意的地方? to : goodname 是这样的,这个5678是我的一个测试服务器开的端口,用于接受连接的,我用vc写了一个测试连接的程序是可以的,但是用php连接就不行了。还有我卸了foxserv,重新配置了Apache,然后发现连接时候的错误原来是“不能做任何连接,因为目标机器积极地拒绝它”,我的php程序和测试服务器都是在同一台机器上,是不是因为这样Apache用socket_connect连接的时候就会出错?希望大虾能帮我看看,谢谢 贴出vc测试的那个代码来看看,学习一下。同一台机器是可以得。只要你的5678端口在listening就行那么connect就可以成功。下面的read,write需要write发送正确格式的(就是服务器的守护进程理解的规定的)格式的字符串服务器的响应可以用read来读取的。---在运行WISe注册或启动WISe服务时,如果出现错误如下:"不能做任何连接,目标机积极的拒绝它" 错误原因:这通常是因为在Windows NT或2000中Windbase Server Service的可执行文件的路径出现了错误解决方法:运行注册表编辑程序Regedit,然后进入查找,输入关键字"Windbase Server",如果成功查找到,双击ImagePath,在弹出的对话框中将c:\winnt\system32\windbase\wbserver -s改为d:\wind\wise\bin\wbserver -s即可!特别注意:出现这样的情况我还建议用下面的方法: (1)(假设装在c盘)c:\wind\wise\bin>instsvc remove 手动卸掉windbase服务 (2) c:\wind\wise\bin>instsvc install c:\wind\wise\bin 手动装载windbase服务 (3) c:\wind\wise\bin>net start "windbase server" 手动启动windbase服务 win?如果php是按模块方式的,则可能出现这个问题,cgi方式就没有问题 下面是我的windows 下面的测试服务器程序:#include <winsock.h>#include <stdio.h>#define TRUE 1void main(){ int sock,length; struct sockaddr_in server; struct sockaddr_in tcpaddr; int msgsock; char buf[1024]; int rval,len; WSADATA wsaData; WSAStartup(0x101,&wsaData); sock = socket(AF_INET,SOCK_STREAM,0); if (sock < 0) { perror("opening stream socket!"); exit(1); } server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr("192.168.94.3"); server.sin_port = 5678; if (bind(sock,(struct sockaddr *)&server,sizeof(server)) < 0) { perror("binding stream error!"); exit(1); } length = sizeof(server); if(getsockname(sock,(struct sockaddr *)&server,&length) < 0) { perror("getting socket name!"); exit(1); } printf("Server address is %s \n",inet_ntoa(server.sin_addr)); printf("Server port is %d \n",server.sin_port); listen(sock,5); len = sizeof(struct sockaddr); do { msgsock = accept(sock,(struct sockaddr *)&tcpaddr,(int *)&len); if(msgsock == -1 ) perror("accept"); else do { memset(buf,0,sizeof(buf)); if((rval = recv(msgsock,buf,1024,0)) < 0) perror("reading stream message"); if( rval == 0 ) printf("ending connection\n"); else { printf("Client IP address %s\n",inet_ntoa(tcpaddr.sin_addr)); printf("-->%s\n",buf); sprintf(buf,"Client IP is : %s",inet_ntoa(tcpaddr.sin_addr)); if(send(msgsock,buf,sizeof(buf),0) < 0) perror("sending on stream socket"); } }while ( rval != 0 ); closesocket(msgsock); }while(TRUE); exit(0);} 下面是用c++写的简单测试程序:#include <winsock.h>#include <stdio.h>#define DATA "half a test..."void main(int argc,char *argv[]){ int sock; struct sockaddr_in server; char buf[1024]; WSADATA wsaData; WSAStartup(0x101,&wsaData); sock = socket(AF_INET,SOCK_STREAM,0); if (sock < 0) { perror("opening stream socket!"); exit(1); } memset(buf,0,sizeof(buf)); char address[16]; memcpy(address,argv[1],16); server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(address); server.sin_port = atoi(argv[2]); if( connect(sock,(struct sockaddr *)&server,sizeof(server)) < 0) { perror("connecting stream socket"); exit(1); } if(send(sock,DATA,sizeof(DATA),0) < 0) perror("sending on stream socket"); if(recv(sock,buf,1024,0) < 0) perror("recving on stream socket"); else printf("receving from server : %s\n",buf); closesocket(sock); exit(0);} 程序非常的简单,只是测试只用运行TestServ之后,运行TestClient 192.168.94.3 5678,可以得到正常的输出结果btw:我刚才在php里面改动了一下,改成$host="www.sina.com.cn",$host_port=80 结果connect就返回成功,所以觉得两个程序应该都没有问题,问题可能是出在Apache的 配置和使用上,但是自己又没有头绪,希望大家能指点一下,谢谢。 谢谢goodname,在link的时候需要加入ws2_32.lib 还有我的机器上没有装windbase server 发现问题了,呵呵,编译我知道的。我发现,实际上,本机监听的是11798端口你把php客户端得向11798发送字符串,就可以这个11798跟5678是什么关系,难道跟网络字节流的顺序有关。这个我有些忘记了,我查一下资料先。 谢谢goodman,情况果然是这样的,这个问题困扰了我好几天了,再次感谢,不知道这个11798和5678到底是什么关系,如果有谁知道的话,告诉一下,还有是不是和Apache有关系呢?btw:goodman是如何知道监听的是11798端口的? 服务器端的程序改作server.sin_port = htons(11798); 那么php客户端就可以用5678端口了htons(11798)=5678 端口号要从一个16位无符号数(u_short类型数)从主机字节顺序转换成网络字节顺序,使用 htons()函数。不知道htons函数是如何实现的,vc的socket编程始终不熟,仅仅是自己测试玩罢了,惭愧。 5678的16进制是162E,11798是2E16,因为网络字节流是高字节在前,我的client里面设置服务器端口的时候使用了htons函数,我自己居然都没有发现,太惭愧了,还耽误了goodman不少时间,真是不应该,sigh 求助,求助 我要注册或者登陆后,跳转到当前浏览的页面,怎么实现? 已可以找到多个记录,为何用while loop 只 insert 一个记录~? PHP网页中的图片和按钮图片是怎么创建的? PHP文件下载程序,怎样获取远程文件大小?跪求! 请高手帮忙,这个是什么意思啊 SimpleXML读取CDATA SECTION的问题 推荐一个支持php,asp,mysql,access商用的虚拟空间! 关于PHP+MSSQL数据库操作编写问题?!想写一个数据库类 有用多WDB文本论坛的,来看看 有没有对文本文件操作很好的类阿? 在PHP中如何获得下来列表的值,不通过表单提交的。谢谢
是这样的,这个5678是我的一个测试服务器开的端口,用于接受连接的,我用vc写了一个测试连接的程序是可以的,但是用php连接就不行了。还有我卸了foxserv,重新配置了Apache,然后发现连接时候的错误原来是“不能做任何连接,因为目标机器积极地拒绝它”,我的php程序和测试服务器都是在同一台机器上,是不是因为这样Apache用socket_connect连接的时候就会出错?希望大虾能帮我看看,谢谢
同一台机器是可以得。只要你的5678端口在listening就行
那么connect就可以成功。
下面的read,write需要write发送正确格式的(就是服务器的守护进程理解的规定的)格式的字符串
服务器的响应可以用read来读取的。---
在运行WISe注册或启动WISe服务时,如果出现错误如下:"不能做任何连接,目标机积极的拒绝它" 错误原因:这通常是因为在Windows NT或2000中Windbase Server Service的可执行文件的路径出现了错误解决方法:运行注册表编辑程序Regedit,然后进入查找,输入关键字"Windbase Server",如果成功查找到,双击ImagePath,在弹出的对话框中将c:\winnt\system32\windbase\wbserver -s改为d:\wind\wise\bin\wbserver -s即可!特别注意:出现这样的情况我还建议用下面的方法: (1)(假设装在c盘)c:\wind\wise\bin>instsvc remove 手动卸掉windbase服务 (2) c:\wind\wise\bin>instsvc install c:\wind\wise\bin 手动装载windbase服务 (3) c:\wind\wise\bin>net start "windbase server" 手动启动windbase服务
#include <winsock.h>
#include <stdio.h>#define TRUE 1void main()
{
int sock,length;
struct sockaddr_in server;
struct sockaddr_in tcpaddr;
int msgsock;
char buf[1024];
int rval,len; WSADATA wsaData;
WSAStartup(0x101,&wsaData); sock = socket(AF_INET,SOCK_STREAM,0);
if (sock < 0)
{
perror("opening stream socket!");
exit(1);
} server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("192.168.94.3");
server.sin_port = 5678;
if (bind(sock,(struct sockaddr *)&server,sizeof(server)) < 0)
{
perror("binding stream error!");
exit(1);
} length = sizeof(server);
if(getsockname(sock,(struct sockaddr *)&server,&length) < 0)
{
perror("getting socket name!");
exit(1);
} printf("Server address is %s \n",inet_ntoa(server.sin_addr));
printf("Server port is %d \n",server.sin_port);
listen(sock,5);
len = sizeof(struct sockaddr); do {
msgsock = accept(sock,(struct sockaddr *)&tcpaddr,(int *)&len);
if(msgsock == -1 )
perror("accept");
else do {
memset(buf,0,sizeof(buf));
if((rval = recv(msgsock,buf,1024,0)) < 0)
perror("reading stream message");
if( rval == 0 )
printf("ending connection\n");
else
{
printf("Client IP address %s\n",inet_ntoa(tcpaddr.sin_addr));
printf("-->%s\n",buf);
sprintf(buf,"Client IP is : %s",inet_ntoa(tcpaddr.sin_addr));
if(send(msgsock,buf,sizeof(buf),0) < 0)
perror("sending on stream socket");
}
}while ( rval != 0 );
closesocket(msgsock);
}while(TRUE);
exit(0);
}
#include <winsock.h>
#include <stdio.h>#define DATA "half a test..."void main(int argc,char *argv[])
{
int sock;
struct sockaddr_in server;
char buf[1024]; WSADATA wsaData;
WSAStartup(0x101,&wsaData); sock = socket(AF_INET,SOCK_STREAM,0);
if (sock < 0)
{
perror("opening stream socket!");
exit(1);
}
memset(buf,0,sizeof(buf)); char address[16];
memcpy(address,argv[1],16);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(address);
server.sin_port = atoi(argv[2]); if( connect(sock,(struct sockaddr *)&server,sizeof(server)) < 0)
{
perror("connecting stream socket");
exit(1);
} if(send(sock,DATA,sizeof(DATA),0) < 0)
perror("sending on stream socket"); if(recv(sock,buf,1024,0) < 0)
perror("recving on stream socket");
else
printf("receving from server : %s\n",buf); closesocket(sock); exit(0);
}
运行TestServ之后,运行TestClient 192.168.94.3 5678,可以得到正常的输出结果btw:我刚才在php里面改动了一下,改成$host="www.sina.com.cn",$host_port=80
结果connect就返回成功,所以觉得两个程序应该都没有问题,问题可能是出在Apache的
配置和使用上,但是自己又没有头绪,希望大家能指点一下,谢谢。
还有我的机器上没有装windbase server
编译我知道的。我发现,实际上,本机监听的是11798端口
你把php客户端得向11798发送字符串,就可以这个11798跟5678是什么关系,难道跟网络字节流的顺序有关。这个我有些忘记了,我查一下资料先。
server.sin_port = htons(11798);
那么php客户端就可以用5678端口了
htons(11798)=5678
htons()函数。不知道htons函数是如何实现的,vc的socket编程始终不熟,仅仅是自己
测试玩罢了,惭愧。