用socket向两个不同服务器发送http请求,是建一个套接字还是两个?我用点一次按纽程序运行一次的方法,用一个线程,建了两个套接字:
SOCKADDR_IN saServer;
LPHOSTENT lphostent;
WSADATA wsadata;
SOCKET hsocket;
int nRet; char dest[1000];
if(WSAStartup(winsock_version,&wsadata))
printf("can't open");
lphostent=gethostbyname(host_name);
if(lphostent==NULL)
printf("lphostent is null");
hsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
saServer.sin_family = AF_INET;
saServer.sin_port = htons(80);
saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list); nRet = connect(hsocket, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
printf("can't connect");
closesocket(hsocket);
return;
}
else
{
printf("connected with %s\n",host_name);
} nRet = send(hsocket, hostname, strlen(hostname), 0);
nRet = recv(hsocket,(LPSTR)dest,sizeof(dest),0);
closesocket(hsocket);
WSACleanup(); SOCKADDR_IN saServer1;
LPHOSTENT lphostent1;
WSADATA wsadata1;
SOCKET hsocket1;
int nRet1; char dest1[1000];
...................
...................
...................
但是运行出现bug:内存不能为“written”请问具体应该怎么做?能给出具体的代码就最好了。
SOCKADDR_IN saServer;
LPHOSTENT lphostent;
WSADATA wsadata;
SOCKET hsocket;
int nRet; char dest[1000];
if(WSAStartup(winsock_version,&wsadata))
printf("can't open");
lphostent=gethostbyname(host_name);
if(lphostent==NULL)
printf("lphostent is null");
hsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
saServer.sin_family = AF_INET;
saServer.sin_port = htons(80);
saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list); nRet = connect(hsocket, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
printf("can't connect");
closesocket(hsocket);
return;
}
else
{
printf("connected with %s\n",host_name);
} nRet = send(hsocket, hostname, strlen(hostname), 0);
nRet = recv(hsocket,(LPSTR)dest,sizeof(dest),0);
closesocket(hsocket);
WSACleanup(); SOCKADDR_IN saServer1;
LPHOSTENT lphostent1;
WSADATA wsadata1;
SOCKET hsocket1;
int nRet1; char dest1[1000];
...................
...................
...................
但是运行出现bug:内存不能为“written”请问具体应该怎么做?能给出具体的代码就最好了。
解决方案 »
- 恢复多次剪切的数据
- 关于MFC中CFrameWnd,CWnd的一点疑问。。
- 有熟练做关于3d建模方面的工程师吗?或者提供个VC+OPENGL群
- 一个内存管理的问题
- 关于窗口边框(GetSystemMetrics())
- 关于面向对象的多线程程序设计的问题~
- return CRect( 0, 0,5,5) + CPoint( x, y );书上看到这个语句,啥意思啊?
- 怎样改变一个静态文本控件的颜色?
- 关于复制生成新文件,怎样使其具有原文件相同的“安全”属性
- DLL中不能用字符串常量么?
- 怎样动态创建一个BUTTON , 使其具有Modal Frame和Owner Draw两种属性???
- 这样的按钮该如何实现啊?!
2,发送
3,接收
4,关闭连接5,建立第2个连接...关闭连接
你应该跟踪执行哪个语句出错的
你不能保证,底层不会一个先send完再send另一个?!而且楼主就用了一个线程,在一个线程里面2个send,肯定是一先一后调用还不是跟用一个socket分2次发送一样
=====================================================================================================你封装一个函数SendToServer(const char *server_ddr,const char *data)
用2个你要连的服务器地址调用2次不就行了么不就跟调用一个一样了,而且显得模块化
afxsocketinit__CSocket g_socket[2];g_socket[0].connect( "127.0.0.1",1234);
g_socket[1].connect( "192.168.1.2",1234 );g_socket[0].send( "dafadfasfsa" ,len);
g_socket[1].send("adfa",len);recv__大概这样
//
//////////////////////////////////////////////////////////////////////#if !defined(AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_)
#define AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_#include <afxinet.h>#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CHttpSocket
{
public:
CHttpSocket();
virtual ~CHttpSocket();
int GetServerState();//返回服务器状态码 -1表示不成功
int GetField(const char* szSession,char *szValue,int nMaxLength);//返回某个域值,-1表示不成功
int GetResponseLine(char *pLine,int nMaxLength);//获取返回头的一行
const char* GetResponseHeader(int &Length);//获取完整的返回头
const char *FormatRequestHeader(char *pServer,char *pObject,long &Length,
char* pCookie=NULL,char *pReferer=NULL,
long nFrom=0,long nTo=0,
int nServerType=0);//格式化请求头
int GetRequestHeader(char *pHeader,int nMaxLength) const;
BOOL SendRequest(const char* pRequestHeader = NULL,long Length = 0);
BOOL SetTimeout(int nTime,int nType=0);
long Receive(char* pBuffer,long nMaxLength);
BOOL Connect(char* szHostName,int nPort=80);
BOOL Socket();
BOOL CloseSocket();
protected:
char m_requestheader[1024]; //请求头
char m_ResponseHeader[1024]; //回应头
int m_port; //端口
char m_ipaddr[256]; //IP地址
BOOL m_bConnected;
SOCKET m_s;
hostent *m_phostent; int m_nCurIndex; //GetResponsLine()函数的游标记录
BOOL m_bResponsed; //是否已经取得了返回头
int m_nResponseHeaderSize; //回应头的大小
};#endif // !defined(AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_)
// HttpSocket.cpp: implementation of the CHttpSocket class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "HttpSocket.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif#define MAXHEADERSIZE 1024
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHttpSocket::CHttpSocket()
{
m_s=NULL;
m_phostent=NULL;
m_port=80;
m_bConnected=FALSE;
for(int i=0;i<256;i++)
m_ipaddr[i]='\0';
memset(m_requestheader,0,MAXHEADERSIZE);
memset(m_ResponseHeader,0,MAXHEADERSIZE);
m_nCurIndex = 0; //
m_bResponsed = FALSE;
m_nResponseHeaderSize = -1;
}CHttpSocket::~CHttpSocket()
{
CloseSocket();
}BOOL CHttpSocket::Socket()
{
if(m_bConnected)return FALSE; struct protoent *ppe;
ppe=getprotobyname("tcp");
///创建SOCKET对象
m_s=socket(PF_INET,SOCK_STREAM,ppe->p_proto);
if(m_s==INVALID_SOCKET)
{
TRACE("socket()函数执行失败!\n");
return FALSE;
} return TRUE;}BOOL CHttpSocket::Connect(char *szHostName,int nPort)
{
if(szHostName==NULL)
return FALSE; ///若已经连接,则先关闭
if(m_bConnected)
{
CloseSocket();
} ///保存端口号
m_port=nPort; ///根据主机名获得IP地址
m_phostent=gethostbyname(szHostName);
if(m_phostent==NULL)
{
TRACE("gethostbyname()函数执行失败!\n");
return FALSE;
}
///连接
struct in_addr ip_addr;
memcpy(&ip_addr,m_phostent->h_addr_list[0],4);///h_addr_list[0]里4个字节,每个字节8位 struct sockaddr_in destaddr;
memset((void *)&destaddr,0,sizeof(destaddr));
destaddr.sin_family=AF_INET;
destaddr.sin_port=htons(80);
destaddr.sin_addr=ip_addr; ///保存主机的IP地址字符串
sprintf(m_ipaddr,"%d.%d.%d.%d",
destaddr.sin_addr.S_un.S_un_b.s_b1,
destaddr.sin_addr.S_un.S_un_b.s_b2,
destaddr.sin_addr.S_un.S_un_b.s_b3,
destaddr.sin_addr.S_un.S_un_b.s_b4); if(connect(m_s,(struct sockaddr*)&destaddr,sizeof(destaddr))!=0)
{
// TRACE(NULL,"connect()函数执行失败!","错误",MB_OK);
return FALSE;
}
///设置已经连接的标志
m_bConnected=TRUE;
return TRUE;
}///根据请求的相对URL输出HTTP请求头
const char *CHttpSocket::FormatRequestHeader(char *pServer,char *pObject, long &Length,
char *pCookie,char *pReferer,long nFrom,
long nTo,int nServerType)
{
char szPort[10];
char szTemp[20];
sprintf(szPort,"%d",m_port);
memset(m_requestheader,'\0',1024); ///第1行:方法,请求的路径,版本
strcat(m_requestheader,"GET ");
strcat(m_requestheader,pObject);
strcat(m_requestheader," HTTP/1.1");
strcat(m_requestheader,"\r\n"); ///第2行:主机
strcat(m_requestheader,"Host:");
strcat(m_requestheader,pServer);
strcat(m_requestheader,"\r\n"); ///第3行:
if(pReferer != NULL)
{
strcat(m_requestheader,"Referer:");
strcat(m_requestheader,pReferer);
strcat(m_requestheader,"\r\n");
} ///第4行:接收的数据类型
strcat(m_requestheader,"Accept:*/*");
strcat(m_requestheader,"\r\n"); ///第5行:浏览器类型
strcat(m_requestheader,"User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)");
strcat(m_requestheader,"\r\n"); ///第6行:连接设置,保持
strcat(m_requestheader,"Connection:Keep-Alive");
strcat(m_requestheader,"\r\n"); ///第7行:Cookie.
if(pCookie != NULL)
{
strcat(m_requestheader,"Set Cookie:0");
strcat(m_requestheader,pCookie);
strcat(m_requestheader,"\r\n");
} ///第8行:请求的数据起始字节位置(断点续传的关键)
if(nFrom > 0)
{
strcat(m_requestheader,"Range: bytes=");
_ltoa(nFrom,szTemp,10);
strcat(m_requestheader,szTemp);
strcat(m_requestheader,"-");
if(nTo > nFrom)
{
_ltoa(nTo,szTemp,10);
strcat(m_requestheader,szTemp);
}
strcat(m_requestheader,"\r\n");
}
///最后一行:空行
strcat(m_requestheader,"\r\n"); ///返回结果
Length=strlen(m_requestheader);
return m_requestheader;
}///发送请求头
BOOL CHttpSocket::SendRequest(const char *pRequestHeader, long Length)
{
if(!m_bConnected)return FALSE; if(pRequestHeader==NULL)
pRequestHeader=m_requestheader;
if(Length==0)
Length=strlen(m_requestheader); if(send(m_s,pRequestHeader,Length,0)==SOCKET_ERROR)
{
TRACE("send()函数执行失败!\n");
return FALSE;
}
int nLength;
GetResponseHeader(nLength);
return TRUE;
}long CHttpSocket::Receive(char* pBuffer,long nMaxLength)
{
if(!m_bConnected)return NULL; ///接收数据
long nLength;
nLength=recv(m_s,pBuffer,nMaxLength,0);
if(nLength <= 0)
{
//MessageBox(NULL,"recv()函数执行失败!","错误",MB_OK);
CloseSocket();
}
return nLength;
}///关闭套接字
BOOL CHttpSocket::CloseSocket()
{
if(m_s != NULL)
{
if(closesocket(m_s)==SOCKET_ERROR)
{
TRACE("closesocket()函数执行失败!\n");
return FALSE;
}
}
m_s = NULL;
m_bConnected=FALSE;
return TRUE;
}int CHttpSocket::GetRequestHeader(char *pHeader, int nMaxLength) const
{
int nLength;
if(int(strlen(m_requestheader))>nMaxLength)
{
nLength=nMaxLength;
}
else
{
nLength=strlen(m_requestheader);
}
memcpy(pHeader,m_requestheader,nLength);
return nLength;
}//设置接收或者发送的最长时间
BOOL CHttpSocket::SetTimeout(int nTime, int nType)
{
if(nType == 0)
{
nType = SO_RCVTIMEO;
}
else
{
nType = SO_SNDTIMEO;
} DWORD dwErr;
dwErr=setsockopt(m_s,SOL_SOCKET,nType,(char*)&nTime,sizeof(nTime));
if(dwErr)
{
TRACE("setsockopt()函数执行失败!\n");
return FALSE;
}
return TRUE;
}//获取HTTP请求的返回头
const char* CHttpSocket::GetResponseHeader(int &nLength)
{
if(!m_bResponsed)
{
char c = 0;
int nIndex = 0;
BOOL bEndResponse = FALSE;
while(!bEndResponse && nIndex < MAXHEADERSIZE)
{
recv(m_s,&c,1,0);
m_ResponseHeader[nIndex++] = c;
if(nIndex >= 4)
{
if(m_ResponseHeader[nIndex - 4] == '\r' && m_ResponseHeader[nIndex - 3] == '\n'
&& m_ResponseHeader[nIndex - 2] == '\r' && m_ResponseHeader[nIndex - 1] == '\n')
bEndResponse = TRUE;
}
}
m_nResponseHeaderSize = nIndex;
m_bResponsed = TRUE;
}
nLength = m_nResponseHeaderSize;
return m_ResponseHeader;
}//返回HTTP响应头中的一行.
int CHttpSocket::GetResponseLine(char *pLine, int nMaxLength)
{
if(m_nCurIndex >= m_nResponseHeaderSize)
{
m_nCurIndex = 0;
return -1;
} int nIndex = 0;
char c = 0;
do
{
c = m_ResponseHeader[m_nCurIndex++];
pLine[nIndex++] = c;
} while(c != '\n' && m_nCurIndex < m_nResponseHeaderSize && nIndex < nMaxLength);
return nIndex;
}int CHttpSocket::GetField(const char *szSession, char *szValue, int nMaxLength)
{
//取得某个域值
if(!m_bResponsed) return -1;
CString strRespons;
strRespons = m_ResponseHeader;
int nPos = -1;
nPos = strRespons.Find(szSession,0);
if(nPos != -1)
{
nPos += strlen(szSession);
nPos += 2;
int nCr = strRespons.Find("\r\n",nPos);
CString strValue = strRespons.Mid(nPos,nCr - nPos);
strcpy(szValue,strValue);
return (nCr - nPos);
}
else
{
return -1;
}
}int CHttpSocket::GetServerState()
{
//若没有取得响应头,返回失败
if(!m_bResponsed) return -1;
char szState[3];
szState[0] = m_ResponseHeader[9];
szState[1] = m_ResponseHeader[10];
szState[2] = m_ResponseHeader[11]; return atoi(szState);
}