CSocket类是怎么回事?

hello_duoduo 2013-07-02 08:46:43
今天用CSocket类在MFC中编写客户端和服务器程序,使用的是UDP通信,问题如下:
客户端采用SentTo()向服务器发送数据,如果服务器的socket没有开启,竟然触发了客户端的OnReceive()函数,但是接收的数据却不是发送的数据,如果服务器的socket开启就不会出现这种情况,我想问:
(1)这是正常情况,还是我的程序有问题?(程序应该没问题的)
(2)这种情况的原因是啥?能否避免这种情况?
求大神指导……[size=13px]
[/size]
...全文
339 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hello_duoduo 2013-07-11
  • 打赏
  • 举报
回复
引用 13 楼 z8323664 的回复:
OnReceive()这个应该是触发目标主机不可达。 因为sendto 是不会判断是否发送成功,如果失败的话可以通过recvfrom知道
程序验证是这么个情况……
z8323664 2013-07-11
  • 打赏
  • 举报
回复
OnReceive()这个应该是触发目标主机不可达。 因为sendto 是不会判断是否发送成功,如果失败的话可以通过recvfrom知道
  • 打赏
  • 举报
回复
原来这是windows的一个特殊设计,给你几篇文章,你仔细看看,看不懂再来问我。 http://support.microsoft.com/kb/263823 http://blog.csdn.net/ccnucjp8136/article/details/4515002 http://bbs.csdn.net/topics/300114542 我想的是你把 wVersionRequested=MAKEWORD(1,1); 这句话改成 wVersionRequested=MAKEWORD(2,0); 或 wVersionRequested=MAKEWORD(2,1); 或 wVersionRequested=MAKEWORD(2,2); 试试,估计可以解决。
hello_duoduo 2013-07-09
  • 打赏
  • 举报
回复
引用 10 楼 cyz7758520 的回复:
[quote=引用 4 楼 hello_duoduo 的回复:] 我的最新的理解和疑问: 我发现这个和WINAPI中的sendto和recvfrom函数的运行是一样的,如下(我已验证过): (1)如果先调用sendto函数,再调用recvfrom函数,此时如果服务器的socket没有开启,recvfrom函数是不会阻塞的,但是会返回错误代码,10054:远端主机强制关闭连接。 (2)如果先调用recvfrom函数,则会阻塞,等待数据的到来。 问题来了:第一种情况的工作机制是什么,即为什么会出现这种情况?? 求大神指导………………
UDP协议是不用去检查远端主机是否存在的,所以recvfrom应该是永远阻塞的才对,UDP协议是没有服务器和客户端的说法的,每一个UDP套接字都可以收发,且发送前不确认对方是否存在,直接发送出去,所以我觉得还是你的代码的问题[/quote]
// socket_client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"Winsock2.h"
#include<stdio.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	//load socket library
	WORD wVersionRequested;
	WSADATA  wsaData;
	int err;

	wVersionRequested=MAKEWORD(1,1);
	err=WSAStartup(wVersionRequested,&wsaData);
	if(err!=0)
	{
		return 0;
	}
	if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return 0;
	}

	//create socket to listen 
	SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(6000);

	char recvBuf[100];
	char sendBuf[100];
	char tempBuf[200];

	int len=sizeof(SOCKADDR);
	// send data 
	while(1)
	{
		printf("please input data\n");
		gets(sendBuf);
		sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSrv,len);
		memset(recvBuf,0,100);
		int count=recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
		 cout<<WSAGetLastError()<<endl; //错误代码10054
		if('q'==recvBuf[0])
		{
			sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
			printf("chat end!\n");
			break;
		}

		sprintf(tempBuf,"%s say:%s",inet_ntoa(addrSrv.sin_addr),recvBuf);
		printf("%s\n",tempBuf);
	}
	//close socket
	closesocket(sockClient);
	WSACleanup();

	return 0;
}
这个程序recvfrom是不会阻塞的,朋友,你看看是什么问题?
  • 打赏
  • 举报
回复
引用 4 楼 hello_duoduo 的回复:
我的最新的理解和疑问: 我发现这个和WINAPI中的sendto和recvfrom函数的运行是一样的,如下(我已验证过): (1)如果先调用sendto函数,再调用recvfrom函数,此时如果服务器的socket没有开启,recvfrom函数是不会阻塞的,但是会返回错误代码,10054:远端主机强制关闭连接。 (2)如果先调用recvfrom函数,则会阻塞,等待数据的到来。 问题来了:第一种情况的工作机制是什么,即为什么会出现这种情况?? 求大神指导………………
UDP协议是不用去检查远端主机是否存在的,所以recvfrom应该是永远阻塞的才对,UDP协议是没有服务器和客户端的说法的,每一个UDP套接字都可以收发,且发送前不确认对方是否存在,直接发送出去,所以我觉得还是你的代码的问题
Eleven 2013-07-04
  • 打赏
  • 举报
回复
sendto()调用成功?检查它的返回值了没有?WSAGetLastError()
hello_duoduo 2013-07-04
  • 打赏
  • 举报
回复
怎么没人回答呢?难道是给的分太低了吗?
hello_duoduo 2013-07-04
  • 打赏
  • 举报
回复
我觉得这是一个不错的问题,求大神出现……
hello_duoduo 2013-07-04
  • 打赏
  • 举报
回复
引用 6 楼 VisualEleven 的回复:
sendto()调用成功?检查它的返回值了没有?WSAGetLastError()
你好! 经检查,SendTo的返回值为消息的大小,WSAGetLaseError的值为0,这应该是SendTo调用成功了。 不知"VisualEleven"是否遇到过此类现象……
smwhotjay 2013-07-04
  • 打赏
  • 举报
回复
udp很蛋疼 不解决丢包和残包的问题 别用udp. tcp就够了
  • 打赏
  • 举报
回复
我觉得应该是你的程序的问题,因为UDP包是不用预先知道对方在不在的,UDP包是直接发送出去的,不管对方是否存在的,应该还是你的程序哪里写错了,贴个代码上来看看
hello_duoduo 2013-07-03
  • 打赏
  • 举报
回复
我的最新的理解和疑问: 我发现这个和WINAPI中的sendto和recvfrom函数的运行是一样的,如下(我已验证过): (1)如果先调用sendto函数,再调用recvfrom函数,此时如果服务器的socket没有开启,recvfrom函数是不会阻塞的,但是会返回错误代码,10054:远端主机强制关闭连接。 (2)如果先调用recvfrom函数,则会阻塞,等待数据的到来。 问题来了:第一种情况的工作机制是什么,即为什么会出现这种情况?? 求大神指导………………
hello_duoduo 2013-07-03
  • 打赏
  • 举报
回复
引用 2 楼 cyz7758520 的回复:
我觉得应该是你的程序的问题,因为UDP包是不用预先知道对方在不在的,UDP包是直接发送出去的,不管对方是否存在的,应该还是你的程序哪里写错了,贴个代码上来看看
你好, 我把情况在描叙清楚一点: (1)从CSocket派生类ClientSocket (2)调用ClientSocket的SendTo函数向服务器端发送数据 (3)重写ClientSocket类的OnReceive函数,并且在其中调用了ReceiveFrom函数接收数据 问题同上,就不重复了。 下面是我的理解和猜想: CSocket是采用消息驱动机制,即只有当数据到达时,会调用OnReceive函数进行处理,对吗? 感谢朋友回复……
hello_duoduo 2013-07-02
  • 打赏
  • 举报
回复
上面的问题或许也可以这样说: “当SendTo()函数的接收端不存在时,这个函数是如何处理的?”

18,356

社区成员

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

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