winsock编程基于数据报套接字的回射程序,其中sendto()函数出现10047错误

lhrlyc 2012-10-10 09:04:03
我用VS2010写了一个基于数据报套接字的回射程序,打开服务器和客户端之后,在客户端输入IP,当客户端运行到SendTo()函数时,出现10047错误,求大神解答!!!!!
代码如下:
#include"winsock2.h"
#pragma comment (lib,"WS2_32.lib")
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <stdlib.h>
#define SEVER_PORT 9900
#define Max_size 1024
using namespace std;
char buf[1024];
int main(int argc,CHAR* argv[])
{
cout<<"*********************UDP回射系统客户端***********************\n"<<endl;
string ip;
WSADATA wsa;
SOCKET client_sock;
struct sockaddr_in client_addr;
struct sockaddr_in ser_addr;
int clilen = sizeof(client_addr);
int serlen = sizeof(ser_addr);
//初始化Socket环境
//初始化Socket动态库
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
cout<<"WSAStartup 无法初始化!"<<endl;
return 1;
}
cout<<"初始化完成...\n"<<endl;
//创建服务器socket
client_sock =socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (client_sock == INVALID_SOCKET)
{
cout<<"socket error!\n"<<endl;
return -1;
}
cout<<"创建完成...\n"<<endl;

cout<<"请输入服务器端IP地址:\n"<<endl;
getline(cin,ip);
memset(buf,0,sizeof(buf));
strcpy_s(buf,ip.c_str());
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(SEVER_PORT);
client_addr.sin_addr.S_un.S_addr = inet_addr(buf);//htonl(INADDR_ANY)
bind(client_sock,(sockaddr *)&client_addr,clilen);
while(1)
{
memset(buf,0,sizeof(buf));
string str;
cout<<"\n客户端发送的数据:"<<endl;
getline(cin,str);
//cout<<"\n"<<endl;
strcpy_s(buf,str.c_str());
if(strcmp(buf,"quit")==0)
{
cout<<"客户端退出"<<endl;
break;
}
if(sendto(client_sock,buf,Max_size,0,(SOCKADDR *)&ser_addr,serlen)==SOCKET_ERROR)/*就是这里*/
{
cout<<WSAGetLastError();
cout<<"出错"<<endl;

//return -1;
}
//cout<<1<<endl;
memset(buf,0,sizeof(buf));
//int buflen = Max_size;
//接收服务器响应的回射内容
recvfrom(client_sock,buf,Max_size,0,(SOCKADDR *)&ser_addr,&serlen);

cout<<"服务器端回射的数据: \n"<< buf<<endl;
}
closesocket(client_sock);
if (WSACleanup() == SOCKET_ERROR)
{
cout<<"cleanup 出错 "<<endl;
return -1;
}
/**/
WSACleanup();
system("pause");
return 0;
}
...全文
477 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuggzu 2012-10-11
  • 打赏
  • 举报
回复
//创建服务器socket
client_sock =socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
这里参数错误,改成:
client_sock =socket(AF_INET,SOCK_DGRAM,IPPROTO_IP);
Feiyan_d 2012-10-11
  • 打赏
  • 举报
回复
参数ser_addr没有赋值,要把ser_addr地址族,地址,端口都填上.这样简单的成序在网上找一个看就行了.这里有WinSock源码:http://download.csdn.net/detail/geoff08zhang/4571358
Eleven 2012-10-10
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

没有错吧,第五个参数是服务器地址。sendto的函数原型是:
int sendto(
SOCKET s,
const char* buf,
int len,
int flags,
const struct sockaddr* to,
int tolen
);
第四个参数是flags,是指定调用函数的方式,一般都是等于0啊,第五个参数是服务器地址。
[/Quote]
说错了,是第5个参数,就是服务器的地址,你有给它的成员赋有效值吗?你上面的代码并给他赋有效值
lhrlyc 2012-10-10
  • 打赏
  • 举报
回复
没有错吧,第五个参数是服务器地址。sendto的函数原型是:
int sendto(
SOCKET s,
const char* buf,
int len,
int flags,
const struct sockaddr* to,
int tolen
);
第四个参数是flags,是指定调用函数的方式,一般都是等于0啊,第五个参数是服务器地址。
Eleven 2012-10-10
  • 打赏
  • 举报
回复
if(sendto(client_sock,buf,Max_size,0,(SOCKADDR *)&ser_addr,serlen)==SOCKET_ERROR)/*就是这里*/
你的sendto的第四个参数错了吧,你需要设置为服务器的地址SOCKADDR_IN
网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列API函数来完成,比如socket、bind、listen、connect、accept、sendsendto、recv、recvfrom等。调用这些API函数有一定的先后次序,有些函数的参数还比较复杂,对于开发者来说,不是很好用。于是,微软的MFC提供了两个类:CAsyncSocket和CSocket,极大地方便了Socket功能的使用。   CAsyncSocket类在较低层次上封装了Windows Socket API,并且通过内建一个(隐藏的)窗口,实现了适合Windows应用的异步机制(Windows Socket API默认情况下工作在阻塞模式,不方便直接在消息驱动的Windows程序上使用)。CSocket类从CAsyncSocket类派生,进一步简化了Socket功能的应用。不过很遗憾,正因为这两个类都内建了一个窗口,它们并不是线程安全的(thread-safe);如果要在多线程环境下应用Socket功能,建议自行封装Socket API函数。 基于TCP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到一个本地地址和端口号上(bind) 3、将套接字设为监听模式,准备接受客户请求(listen) 4、等待客户请求,请求到来时接受请求,建立链接,并返回 一个新的基于此次通信的套接字(accept) 5、用返回的套接字和客户端进行通信(send、recv) 6、返回,等待另一客户请求 7、关闭套接字 基于TCP的socket编程的客户端程序流程如下: 1、创建套接字 2、向服务器端发送请求(connect) 3、和服务器端进行通信(send、recv) 4、关闭套接字 基于UDP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到本地地址和端口号上(bind) 3、等待接收数据(recvfrom) 4、关闭套接字 基于UDP的socket编程的客户端程序流程如下: 1、创建套接字 2、和服务器端进行通信(sendto) 3、关闭套接字 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。   阻塞套接字是指执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的。   对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步非阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。   MFC提供了一个异步类CAsyncSocket,它封装了异步、非阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、非阻塞等概念,开发人员无需了解异步、非阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。
课程名称 计算机网络 实验序号 实验五 实验项目 Ping程序的设计与实现 2017年 03月 25 日 实验告要求 1、实验告封面填表说明(每份实验告必须附上封面) (1)课程名称:要求与实验大纲和实验指导书中的课程名称一致。 (2)实验序号:指该课程的第几个实验。 (3)实验项目:要求与实验大纲和实验指导书中的实验项目一致。 (4)实验地点:填写完成该实验项目所在的实验室名称。 (5)实验学时:要求与实验大纲和实验指导书中完成该实验项目所需学时一致。 (6)实验类型:是指演示性、操作性、验证性、综合性、设计性。 演示性:教师操作,学生观察,验证理论、说明原理和方法。 操作性:学生按要求动手拆装、调试实验装置或上机操作,掌握其基本原理和方法。 验证性:按实验指导书(教材)要求,由学生通过操作验证所学理论,加深对理论、 知识的理解,掌握基本实验知识、方法、技能、数据处理等。 综合性:实验容涉及本课程的综合知识或相关课程的知识,运用多的知识、多种方法 ,按要求或自拟实验方案进行实验。主要培养学生综合运用所学知识、实验方法和实验 技能,以培养其分析、解决问题的能力。 设计性:给定实验目的、要求和实验条件,学生自己设计实验方案并加以实现的实验 。学生独立完成从查阅资料、拟定实验方案、实验方法和步骤(或系统分析和设计)、 选择仪器设备(或自行设计缺制作)进行实验并完成实验全过程,形成实验告,培养 学生自主实验的能力。 2、实验告的格式 "软件类实验告格式"公共课实验告"硬件类实验告格式 " " "格式 " " "序 "要求 "序"要求 "序"要求 " "号 " "号" "号" " "1 "实验目的及要求"1 "实验目的及 "1 "实验预习 "实验目的实验原理及容(简" " " " "要求 " " "明扼要,主要是实验接线图" " " " " " " ") " "2 "实验原理与容 "2 "实验步骤 " " "所用仪器设备 " "3 "实验软硬件环境"3 "操作要点 " " "预习思考题 " "4 "实验过程(实验"4 "实验结果 "2 "实验原始 "画出实验所需要的各种记录" " "步骤、记录、数" " " "记录(经 "表格 " " "据、分析) " " " "实验指导 " " " " " " " "教师签名 " " " " " " " "认可) " " "5 "测试/调试及实 "5 "实验问题 "3 "实验告 "数据处理(数据表格、计算" " "验结果分析 " " " " "结果、误差、结果表达、曲" " " " " " " "线图等) " "6 "实验结论与体会"6 "小结及讨论 " " "结论 " " " " " " " "讨论 " 3、教师批改学生实验告要求 (1)批改:全部批改及更正错误。 (2)评分:按百分制评分,不能评分为"优、良、中、差"或"A、B、C"。 (3)签名及批改日期:任课教师必须在每份学生实验告中签名和写上批改日期。 (4)成绩:填写学生实验成绩表,实验成绩作为考试成绩评定的依据。 (4)评语:任课教师批改学生实验告时,应给出简明扼要的评语。 "成绩: " "教" " "师" " "评" " "语" " " "指导教师签名: 批阅日期: " "一、实验目的及要求 " " " "加深对ICMP协议的理解 " "熟悉原始套接字的使用方法 " "掌握PING程序的实现流程 " " " " " "二、实验原理与容 " " " "一种网络诊断工具 " "发送ICMP回送请求文 " "接收 ICMP回送应答文 " " " "IP文格式 " " " "WinSock原始套接字的使用方法与API函数 " "Winsock原始套接字编程过程中,服务器端/客户端的编程都按照以下步骤: " "初始化套接字(WSAStartup) " "创建套接字(socket或WSASocket) " "向服务器通信(sendto/recvfrom) " "关闭套接字(closesocket) " "结束使用套接字(WSACleanup) " " " " " "三种WinSock地址结构 " "用的Winsock地址结构sockaddr " ",针对各种通信域的套接字,存储它们的地址信息。 " "专门针对Internet 通信域的Winsock地址结构sockaddr_in " "专用于存储IP地址的结构in_addr " " " "三、实验软硬件环境 " " " "运行Windows XP/ Windows Server 2003/Windows 7操作系统的PC一台 " "Visual C++6.0/ Visual Studio 2005/Visual Studio 2010开发环境 " " " "四、实验
c++ udp通信发送实例 ///////////////////////////////////////////////////////// // initsock.h文件 #include #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib class CInitSock { public: CInitSock(BYTE minorVer = 2, BYTE majorVer = 2) { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0) { exit(0); } } ~CInitSock() { ::WSACleanup(); } }; ////////////////////////////////////////////////////////// // UDPClient文件 #include "../common/InitSock.h" #include CInitSock initSock; // 初始化Winsock库 int main() { // 创建套节字 SOCKET s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(s == INVALID_SOCKET) { printf("Failed socket() %d \n", ::WSAGetLastError()); return 0; } // 也可以在这里调用bind函数绑定一个本地地址 // 否则系统将会自动安排 // 填写远程地址信息 sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4567); // 注意,这里要填写服务器程序所在机器的IP地址 // 如果你的计算机没有联网,直接使用127.0.0.1即可 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 发送数据 char szText[] = " TCP Server Demo! \r\n"; ::sendto(s, szText, strlen(szText), 0, (sockaddr*)&addr, sizeof(addr)); ::closesocket(s); return 0; } ////////////////////////////////////////////////////////// // UDPServer.cpp文件 #include "../common/InitSock.h" #include CInitSock initSock; // 初始化Winsock库 int main() { // 创建套节字 SOCKET s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(s == INVALID_SOCKET) { printf("Failed socket() \n"); return 0; } // 填充sockaddr_in结构 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(4567); sin.sin_addr.S_un.S_addr = INADDR_ANY; // 绑定这个套节字到一个本地地址 if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) { printf("Failed bind() \n"); return 0; } // 接收数据 char buff[1024]; sockaddr_in addr; int nLen = sizeof(addr); while(TRUE) { int nRecv = ::recvfrom(s, buff, 1024, 0, (sockaddr*)&addr, &nLen); if(nRecv > 0) { buff[nRecv] = '\0'; printf(" 接收到数据(%s):%s", ::inet_ntoa(addr.sin_addr), buff); } } ::closesocket(s); }

18,356

社区成员

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

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