写一个查看远端主机上文件列表的程序,A取B的文件列表时,B循环调用Send函数每次发送一个文件名。一般没有问题,但当文件数较多时(比如c:\windows\system32目录下,有两千多文件和文件夹),就会出现错误void Send(char *strIP, int nPort)
{
if((*strIP <= '9') && (*strIP >= '0'))
{
if((ip = inet_addr(strIP)) == INADDR_NONE)
{
AfxMessageBox("bad ip."); //这里有时出错,我下断点看到出错时strIP =127.0.0.1,是正
return FALSE; //确的,但就是会走到这里
}
}
//......
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr = *(in_addr*)&ip;
m_hSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( m_hSock == INVALID_SOCKET)
{
AfxMessageBox("invalid socket");
int nErr = WSAGetLastError();
return FALSE;
}
int nRet;
nRet = connect(m_hSock,(sockaddr*)&addr,sizeof(sockaddr));
if ( nRet == SOCKET_ERROR )
{
int nErr = WSAGetLastError();
AfxMessageBox("connect err"); //这里错的几率较大,错误号10060
return FALSE;
}
//...
closesocket(m_hSock);
接收数据部分代码Listen()
{
m_hSockL = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_hSockL == SOCKET_ERROR)//这里面查错的代码都省略了
{
return false;
}
sockaddr_in local;
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(8000);
if (bind(m_hSockL, (sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
{
return false;
} if (listen(m_hSockL, SOMAXCONN) == SOCKET_ERROR)
{
return false;
}
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AcceptThread, (LPVOID)this, 0, NULL);
CloseHandle(hThread);
return true;
}
DWORD WINAPI AcceptThread(LPVOID lParam)
{ //...
SOCKET sRecv;
while(1)
{
sockaddr_in client;
int iAddrSize = sizeof(client);
sRecv = accept(pClass->m_hSockL,(sockaddr*)&client, &iAddrSize);
if( sRecv == INVALID_SOCKET)
{
char szErr[256] = {0};
sprintf(szErr, "accept failed:%d", WSAGetLastError());
return 0;
}
//...
HANDLE hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)RecvThread, (LPVOID)sRecv, 0, NULL);
CloseHandle(hThread);
}
return 0;}
DWORD WINAPI RecvThread(LPVOID lParam)
{
char szBuf[BUFLEN] = {0};
int nRet = 0,nCount = 0,nTime = 1000*5; //nTime是超时值
SOCKET sock = (SOCKET)lParam;
do
{
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTime, sizeof(nTime)); //设置超时
nRet = recv(sock, szBuf+nCount, BUFLEN-nCount, 0);
nCount += nRet;
}while( (nRet>0) && (nCount<BUFLEN) );
//...
closesocket(sock);
return 0;
}我之前用了一下WSAAsyncSelect,但是发送速度快了会有FD_READ消息收不到的情况,加了确认重传包是不丢了,但是效率却低了很多,所以改回同步的,现在又遇到这个问题。怎么样能让传输速度尽可能的快,而且不出现丢包之类的错误呢?
{
if((*strIP <= '9') && (*strIP >= '0'))
{
if((ip = inet_addr(strIP)) == INADDR_NONE)
{
AfxMessageBox("bad ip."); //这里有时出错,我下断点看到出错时strIP =127.0.0.1,是正
return FALSE; //确的,但就是会走到这里
}
}
//......
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(nPort);
addr.sin_addr = *(in_addr*)&ip;
m_hSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( m_hSock == INVALID_SOCKET)
{
AfxMessageBox("invalid socket");
int nErr = WSAGetLastError();
return FALSE;
}
int nRet;
nRet = connect(m_hSock,(sockaddr*)&addr,sizeof(sockaddr));
if ( nRet == SOCKET_ERROR )
{
int nErr = WSAGetLastError();
AfxMessageBox("connect err"); //这里错的几率较大,错误号10060
return FALSE;
}
//...
closesocket(m_hSock);
接收数据部分代码Listen()
{
m_hSockL = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_hSockL == SOCKET_ERROR)//这里面查错的代码都省略了
{
return false;
}
sockaddr_in local;
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(8000);
if (bind(m_hSockL, (sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
{
return false;
} if (listen(m_hSockL, SOMAXCONN) == SOCKET_ERROR)
{
return false;
}
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AcceptThread, (LPVOID)this, 0, NULL);
CloseHandle(hThread);
return true;
}
DWORD WINAPI AcceptThread(LPVOID lParam)
{ //...
SOCKET sRecv;
while(1)
{
sockaddr_in client;
int iAddrSize = sizeof(client);
sRecv = accept(pClass->m_hSockL,(sockaddr*)&client, &iAddrSize);
if( sRecv == INVALID_SOCKET)
{
char szErr[256] = {0};
sprintf(szErr, "accept failed:%d", WSAGetLastError());
return 0;
}
//...
HANDLE hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)RecvThread, (LPVOID)sRecv, 0, NULL);
CloseHandle(hThread);
}
return 0;}
DWORD WINAPI RecvThread(LPVOID lParam)
{
char szBuf[BUFLEN] = {0};
int nRet = 0,nCount = 0,nTime = 1000*5; //nTime是超时值
SOCKET sock = (SOCKET)lParam;
do
{
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTime, sizeof(nTime)); //设置超时
nRet = recv(sock, szBuf+nCount, BUFLEN-nCount, 0);
nCount += nRet;
}while( (nRet>0) && (nCount<BUFLEN) );
//...
closesocket(sock);
return 0;
}我之前用了一下WSAAsyncSelect,但是发送速度快了会有FD_READ消息收不到的情况,加了确认重传包是不丢了,但是效率却低了很多,所以改回同步的,现在又遇到这个问题。怎么样能让传输速度尽可能的快,而且不出现丢包之类的错误呢?
解决方案 »
- tab 控件问题,虾儿们在哪里?
- VC和MATLAB混合编程--模糊控制问题(帮顶有分)
- 在放100分在这里!串口的问题!!在单文档不能发数据而在对话框中可以!在线和各位讨论!!!!感兴趣的进来!!!
- 有没有写木马的高手呀,偶定做,价格商量
- 关于图象处理
- 请问如下两种导出dll函数的方式有何区别,为什么一种可以被调用,另一种不可以?
- 全金奉送:一个网络、视频、音频传输问题的解决思想。(进者有分)
- 各位大虾,帮忙思考一下这个有关网络传输的问题,进者有分!!!
- 结果集是只读的?100分在线等待,谢谢
- 好消息!(买不起书的请进!)
- 往数据表里插入记录后,怎么移动记录的指针?
- 请教各位高手,关于读取图片的问题
ip是unsigned long类型的。
关于inet_addr这个函数,MSDN里没有说明它出错可以用WSAGetlasterror之类的函数取错误码,我试了WSAGetlasterror和GetLastError,返回值都是0。
单步调试的时候,在connect那里有时会返回10049错误号。
你的connect像阻塞模式,返回失败10062,就说明对方拒绝连接哦
改成
addr.s_addr = htonl(ip);
不是什么都可以强制类型转换的
nRet = connect(m_hSock,(sockaddr*)&addr,sizeof(sockaddr));
if ( nRet == SOCKET_ERROR )
{
int nErr = WSAGetLastError();
AfxMessageBox("connect err"); //这里错的几率较大,错误号10060
return FALSE;
}
//...
closesocket(m_hSock);”你是每send一个文件就要connect一次吗?
如果是这样的话,很有可能你closesocket时,socket还未真正的关闭,而这时你又connect,所以会导致出错。
建议你可以
“
BOOL bDontLinger = FALSE;
setsockopt( s, SOL_SOCKET, SO_DONTLINGER, ( const char* )&bDontLinger, sizeof( BOOL ) );
”在调用closesocket()后强制关闭,不经历TIME_WAIT的过程。但是这样有个问题就是,会send还未完成,就close了。
所以也不太建议这样做。
但是可以这样做。
“
struct linger {
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff = 1; //在调用closesocket()时还有数据未发送完,允许等待
// 若m_sLinger.l_onoff=0;则调用closesocket()后强制关闭
m_sLinger.l_linger = 5; //设置等待时间为5秒
setsockopt( s, SOL_SOCKET, SO_LINGER, ( const char* )&m_sLinger, sizeof( linger ) );”
可以将“m_sLinger.l_linger = 5; ”设置下时间,或者“m_sLinger.l_linger = 0;表示等待的时间为无穷大,即直到send完成为止。 ”