我封装的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);
}
//
...全文
129 17 打赏 收藏 转发到动态 举报
写回复
用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

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

标志可以决定是不是阻塞吗?
非常不错,c#入门经典哦! 关于socket的,适合初学者。 #socket编程基础 Microsoft.Net Framework为应用程序访问Internet提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的可以开发多种网络应用程序。.Net采用的分层结构允许应用程序在不同的控制级别上访问网络,开发人员可以根据需要选择针对不同的级别编制程序,这些级别几乎囊括了Internet的所有需要 --从socket套接字到普通的请求/响应,更重要的是,这种分层是可以扩展的,能够适应Internet不断扩展的需要。 抛开ISO/OSI模型的7层构架,单从TCP/IP模型上的逻辑层面上看,.Net可以视为包含3个层次:请求/响应层、应用协议层、传输层。 WebReqeust和WebResponse 代表了请求/响应层,支持Http、Tcp和Udp的组成了应用协议层,而Socket处于传输层。 传输层位于这个结构的最底层,当其上面的应用协议层和请求/响应层不能满足应用程序的特殊需要时,就需要使用这一层进行Socket套接字编程。 而在.Net,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现。System.Net 命名空间的所有其他网络访问都建立在该套接字 Socket实现之上,如TCPClient、TCPListener 和 UDPClient 封装有关创建到 Internet 的 TCP 和 UDP 连接的详细信息;NetworkStream则提供用于网络访问的基础数据流等,常见的许多 Internet服务都可以见到Socket的踪影,如Telnet、Http、Email、Echo等,这些服务尽管通讯协议Protocol的定义不同,但是其基础的传输都是采用的Socket。 其实,Socket可以象流Stream一样被视为一个数据通道,这个通道架设在应用程序端(客户端)和远程服务器端之间,而后,数据的读取(接收)和写入(发送)均针对这个通道来进行。 可见,在应用程序端或者服务器端创建了Socket对象之后,就可以使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据; 针对Socket编程,.NET 框架的 Socket Winsock32 API 提供的套接字服务的托管代码版本。其为实现网络编程提供了大量的方法,大多数情况下,Socket 方法只是将数据封送到它们的本机 Win32 副本并处理任何必要的安全检查。如果你熟悉 Winsock API函数,那么用Socket编写网络程序会非常容易,当然,如果你不曾接触过,也不会太困难,跟随下面的解说,你会发觉使用 Socket开发windows 网络应用程序原来有规可寻,它们在大多数情况下遵循大致相同的步骤。
2018年软件学院C++课程设计 课程设计目的: 1、熟悉利用面向对象的方法以及C++的编程思想来完成系统的设计; 2、锻炼学生在设计的过程,建立清晰的层次,应用继承和多态等面向对象的编程思想; 3、通过本课程设计,加深对面向对象程序设计课程所学知识的理解,熟练掌握和巩固C++语言的基本知识和语法规范,深刻体会面向对象的编程思想,掌握使用面向对象程序设计语言C++,学会编写结构清晰、风格良好的C++语言程序,从而具备利用计算机编程分析解决综合性实际问题的初步能力。 课程设计题目:模拟即时通信系统实现 一、题目描述 基于社交的即时通信是腾*公司的主要业务,先后有QQ、微信、微博等服务,可能还将继续推出微商、微唱、微走、微笑等产品。这些软件既可以独立提供服务,又互相辉映关联。腾*公司希望对各系统进行整合形成统一的立体社交软件平台。现请完成该平台的设计并实现。要求如下: 1、用户基本信息: 号码ID,昵称,出生时间,T龄(号码申请时间)、所在地、好友列表、群列表。 微博与QQ共享ID,微信采用独立ID,但是可以与QQ号码绑定对应。其他微X产品也分为这两种情况。 2、好友管理 (1)实现各功能好友信息的添加、修改、删除、查询的功能。 (2)可以查询微X 之间各自共同好友。如微信可以添加QQ推荐好友。 3、群管理 (1)设定每个微X功能已有1001、1002、1003、1004、1005、1006等群号。 (2)加入群、退出群、挨T、查询群成员等。 (3)不同微X之间群的理念不同,比如:QQ群可以申请加入,而微信群则只能推荐加入;QQ群允许设置临时讨论组(子群),微信群则不允许;QQ群有以群主为核心的管理员制度,而微信群仅有群主为特权账号。 4、开通管理 用户可以选择自己开通该平台的N个微X服务。 5、登录管理 各微X之间只要有一个服务登录,则其它服务简单确认后视为自动登录。 6、功能展示要求(main函数) (1)设计约定。开通服务情况、群成员信息和好友信息可以预先保存到文件,在系统启动时将这些信息加载到内存; (2)一个服务登录后,本人开通的其它所有服务均进入开通状态。 (3)服务之间可以依据本人开通的任意另外一个服务的好友添加好友。 (4)展示一个服务当前群的特色功能;在群成员数据不受伤害的前提下,动态变换为其他型群的管理特色。 (5)实现QQ的点对点的TCP通信的收发功能。(选做)提示: a)需要加载ws2_32.lib静态库,打开头文件winsock.h。 b)百度IP地址、端口等概念; c)百度socket编程,关注bind、listen、accept、connect、send、receive等函数用法。 二、技术层次要求及说明 1、基本层次。 完成上述功能要求,所采用技术不限,比如采用纯面向过程思想实现; 2、支持对象层次。 正确完成了的切割,利用对象技术实现。 (1)容器主要包括:例如,微X成员管理。 (2)其它主要包括:例如,微X信息、群信息、好友信息。 3、抽象、封装层次 采用了继承或者组合实现复用,对数据成员提供了必要的接口保护; (1)抽象出了基础,并被其它功能复用; (2)如好友维护、群信息维护等操作均应该提供接口形式; 4、面向对象层次 支持多态功能,支持依据设计原则的优化。 好友管理、群管理等; 5、优化提高层次 (1)提供简便菜单,以1、2等数字区分几功能,并允许返回菜单; (2)I/O操作支持。基本功能,已有设定信息,在初始化时候可以固化在程序代码,也可以存放在文件,每次容器实例化时读入,析构时写回文件,以实现断电保存。 (3)可扩展性支持,需要考虑群、好友等与主要服务之间的关系; (4)灵活性支持。群的管理模式动态可变; (5)程序有必要的注释; (6)可以采用UML工具画出简单图 (7)为防止不诚信行为,要求的设计均以独立文件存在,且所有的名称后面应有自己的姓名缩写,如张三设计的QQ信息名称:TencentZhS。 三、设计步骤(参考 ): 在清楚上述系统功能要处理是什么的基础上,考虑用如下方式来设计 1、确定所需的及其相互间的关系。 (1)要从问题归纳出一个概念或实体,从这些概念或实体出发建立相应的。 (2)尽量使小而简单,以使其看起来容易理解。 (3)充分利用封装以增加的可靠性,以便使用时保证更加可靠。 (4)通过继承建立族,以方便使用多态性。 2、确定每个的实现。 (1)考虑的对象应该如何构造和析构。 (2)考虑的成员函数的建立。 (3)综合考虑各个在命名和功能方面有哪些共性。 3、细化有关的,描述他们之间的相互关系,即关系和对象关系。 4、描述本系统的界面,通过分别定义成员的不同属性,为抽象和实现提供分离的接口。 四、设计工具 1、设计工具:建议使用.net 系列的C++ 编译器,但不局限于此。 2、不提倡使用MFC和可视化开发技术。 五、设计报告 (报告的具体格式附后) 六、考核方式 1、在设计结束前的最后一天检查程序并接受质疑。 2、检查程序前须提交设计报告(按提交报告的先后顺序检查程序)。 七、考核标准: 参照5个技术层次划分。 八、课程设计后作业(不考核) 引入可视化设计,在本课程设计基础上实现可视化QQ即时通信功能,包括: 多人聊天;聊天记录查询。需要涉及知识如下: 1、网络通信编程; 2、可视化编程; 3、多线程编程; 4、数据库编程;

18,356

社区成员

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

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