我封装的Winsock 类 中的 send 和 receive 有问题,帮忙看看

TianGo123 2002-12-26 12:08:34
int CSynchronizationSocket::SendData(UINT nID, const void* pData, int nDataLength)
{
int nSend;

nSend = send(m_socket, (LPSTR)pData, nDataLength,
MSG_DONTROUTE);
if(nSend == SOCKET_ERROR)
{
return 0;
}
else
{
return nSend;
}
}

int CSynchronizationSocket::GetData(const void* pData, int nDataLength)
{
int nAmount;

nAmount = recv(m_socket, (LPSTR)pData, nDataLength, MSG_PEEK);
if(nAmount == SOCKET_ERROR)
{
return 0;
}
else
{
return nAmount;
}
}

用 byte 来发送文件得不到。

怎么解决呢?

//
recv(m_socket, (LPSTR)pData, nDataLength, MSG_PEEK);
仿照的是mfc的封装。
int CAsyncSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
{
return send(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
}
//
...全文
135 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
下面是 mfc 的做法

非阻塞
int CAsyncSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{
return recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
}

//怎么是非阻塞呢?
//不明白

阻塞
int CSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
{
if (m_pbBlocking != NULL)
{
WSASetLastError(WSAEINPROGRESS);
return FALSE;
}

int nLeft, nWritten;
PBYTE pBuf = (PBYTE)lpBuf;
nLeft = nBufLen;

while (nLeft > 0)
{
nWritten = SendChunk(pBuf, nLeft, nFlags);
if (nWritten == SOCKET_ERROR)
return nWritten;

nLeft -= nWritten;
pBuf += nWritten;
}
return nBufLen - nLeft;
}
realdreamer 2002-12-26
  • 打赏
  • 举报
回复
为什么要用这个标志?

MSG_DONTROUTE
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
那我现在要把send,receive封装成阻塞的类的函数,怎么办呢?

int CSynchronizationSocket::GetData(const void* pData, int nDataLength)
{
int nAmount;

nAmount = recv(m_socket, (LPSTR)pData, nDataLength, MSG_PEEK);
if(nAmount == SOCKET_ERROR)
{
return 0;
}
else
{
return nAmount;
}
}

经测试,是非阻塞的。
有点莫名其妙。
Bind 2002-12-26
  • 打赏
  • 举报
回复
你的描述不够清楚。


send(m_socket, (LPSTR)pData, nDataLength,
MSG_DONTROUTE);
MSG_DONTROUTE标志要求传送层不要将它发出的包路由出去。


recv(m_socket, (LPSTR)pData, nDataLength, MSG_PEEK);
MSG_PEEK标志使有用的数据复制到所提供的接收缓冲内,但是没有从系统缓冲中将它删除。该标志不仅导致性能下降,在某些情况下还可能不可靠。返回的数据可能没有反向出真正有用的数量。与此同时,把数据留在系统缓冲,可容纳接入数据的系统空间就会越来越少。其结果便是,系统减少各发送端的TCP窗口容量。
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
搜索一下这个论坛,有些很好的回答,你自己看看几个帖子就差不多了

然后要自己实践
lv_zemin 2002-12-26
  • 打赏
  • 举报
回复
兄弟,解释一下非阻塞和阻塞区别?初次接触Socket
Bind 2002-12-26
  • 打赏
  • 举报
回复
1、因为CAsyncSocket调用了WSAAsyncSelect。

2、标志作用见上面的回复。
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
5点前结帐
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
可以传输byte的

哈哈,真是失败啊

我总结一下我的问题:

我刚开始的函数是阻塞的,我觉得不是阻塞的是错的。
我的封装也是可以的。

有一点我不明白了:

1

非阻塞
int CAsyncSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{
return recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
}

//怎么是非阻塞呢?
//不明白

2

关于发送和接受的那两个标志,我还不清楚,
Bind 2002-12-26
  • 打赏
  • 举报
回复
可以
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
哎呀,是我自己的错。

不好意思啊。

我知道了

socket = pSocket->Accept((struct sockaddr FAR *)&clientaddr, &length);
chatsocket.SetSocket(socket);

::AfxBeginThread(SendThread, pSocket);

是这里了::AfxBeginThread(SendThread, &chatsocket);


哈哈。

我心都慌了(傍边有主管催啊)


应该还有别的问题,就是不能发送mp3文件的问题了

int CSynchronizationSocket::GetData(const void* pData, int nDataLength)
{
int nAmount;

nAmount = recv(m_socket, (LPSTR)pData, nDataLength, MSG_PEEK);
if(nAmount == SOCKET_ERROR)
{
return 0;
}
else
{
return nAmount;
}
}

这里的const void* pData , (LPSTR)pData
指针的转化行不行呢?
可以传输byte吗?
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
是阻塞的,对不起,是我自己搞错了

int CSynchronizationSocket::SendData(UINT nID, const void* pData, int nDataLength)
{
int nSend;

nSend = send(m_socket, (LPSTR)pData, nDataLength,
MSG_DONTROUTE);//返回为0
if(nSend == SOCKET_ERROR)
{
int i = WSAGetLastError();// i = 10057
return 0;
}
else
{
return nSend;
}
}


//10057
由于套接字没有连接并且 (当使用一个 sendto 调用发送数据报套接字时) 没有提供地址,发送或接收数据的请求没有被接受。


UINT AcceptThread(LPVOID pParam)
{
if(pParam == NULL)
{
return 0;
}
bool bFirstVisit = true;

CSynchronizationSocket chatsocket;
CSynchronizationSocket * pSocket = (CSynchronizationSocket *)pParam;

while(true)
{
SOCKET socket;
struct sockaddr_in clientaddr;
int length;

length = sizeof(struct sockaddr_in);

socket = pSocket->Accept((struct sockaddr FAR *)&clientaddr, &length);
chatsocket.SetSocket(socket);

::AfxBeginThread(SendThread, pSocket);
}


UINT SendThread(LPVOID pParam)
{
if(pParam == NULL)
{
return 0;
}
CMutex mutex;
mutex.Lock();

CSynchronizationSocket * pSocket = (CSynchronizationSocket *)pParam;


(
UINT nAmount = 0;
UINT nSend;

byte * buffer = new byte[BUFFERSIZE];

int nRead;



memset(buffer, '\54', sizeof(buffer));

nRead = 64;
int i;
nSend = pSocket->SendData(i, buffer, nRead,
MSG_DONTROUTE);
***************** nSend = 0 怎么回事?******************************
delete buffer;


mutex.Unlock();
return 1;
}


Bind 2002-12-26
  • 打赏
  • 举报
回复
这个不复杂啊。你只要不去调用诸如WSAsyncSelect之类的函数,并且未使用ioctrlsocket设置SOCKET属性为FIOBIO就可以了。另外你的不能接收到是什么意思?recv不能返回还是返回了但是返回长度值为0?
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
问题:

1 上面的我的函数是非阻塞的
2 不能接受到,(不过可能是与问题1有关的)
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
1 我想要阻塞的自己封装的winsock类的函数SendData,ReceiveData
2 我想使用阻塞的SendData发送mp3文件,用阻塞的ReceiveData接受mp3文件

我以前使用CAsyncSocket做到过传输文件。我现在要用自己的类。

请帮忙。
Bind 2002-12-26
  • 打赏
  • 举报
回复
你现在倒底遇到了什么问题呢?
TianGo123 2002-12-26
  • 打赏
  • 举报
回复
to realdreamer(楼主英明,贫僧久仰大名,特来拜见) ( ) 信誉:105

标志不重要吧。
我可以选别的标志。

标志可以决定是不是阻塞吗?

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧