Winsock UDP编程示例:客户端与服务器端教程

版权申诉
0 下载量 151 浏览量 更新于2024-10-12 收藏 44KB RAR 举报
资源摘要信息:"该资源为一个简单的Windows平台下使用Winsock实现UDP通信的程序,包含客户端(Client)和服务器端(Server)两个部分。该程序对初学者学习Winsock编程特别有帮助。通过学习这个示例程序,初学者可以了解到Winsock API在UDP协议上的基本使用方法,包括创建套接字、绑定地址、发送和接收数据、以及关闭套接字等操作。此外,该程序还可能包含了错误处理、事件处理等编程技巧,是学习网络编程的基础教材。" 知识点概述: 1. Winsock API:Winsock是Windows Sockets的缩写,是Windows平台上用于网络通信的一组API。UDP程序使用Winsock API来实现数据的发送和接收。Winsock提供了丰富的接口,可以用来处理网络通信中的各种需求。 2. UDP协议:UDP(User Datagram Protocol)是无连接的网络协议,它不保证数据包的送达和顺序,但发送和接收过程非常快,适用于对实时性要求较高的应用,如音频和视频传输、在线游戏等。UDP程序通常包括客户端和服务器端,服务器端负责监听来自客户端的请求,客户端则向服务器发送数据。 3. 客户端(Client):在UDP通信中,客户端是主动发送请求到服务器端的程序。客户端程序通常会创建一个UDP套接字,然后绑定到一个本地端口上,再通过该套接字发送数据包到服务器的IP地址和端口。 4. 服务器端(Server):服务器端在UDP通信中扮演着监听和响应客户端请求的角色。它同样创建一个UDP套接字,然后绑定到一个已知端口上,等待客户端的数据包。一旦接收到数据,服务器可以进行相应的处理并发送响应数据包回客户端。 5. 错误处理:在实际的网络编程中,错误处理是非常重要的一个环节。错误处理可以确保程序在遇到网络故障、资源不足等问题时能够正确响应,避免程序异常崩溃。 6. 事件处理:在某些实现中,服务器可能需要同时处理多个客户端的请求。事件处理可以让服务器在不阻塞主线程的情况下响应多个事件,提高了程序的效率和响应性。 7. 编程技巧:UDP程序可能还涵盖了多线程编程、网络地址转换、字节序转换(big-endian和little-endian)等编程技巧,这些都是网络编程中常见且重要的知识点。 8. 学习资源:该资源对于初学者来说是一个非常实用的学习材料。通过分析和理解服务器端和客户端的代码,初学者可以逐步构建自己对于Winsock API以及UDP协议的理解,从而为更深入的网络编程学习打下坚实基础。 注意:在使用该资源时,用户应当具备一定的编程基础,并理解UDP协议的工作原理以及Windows网络编程的基本概念。此外,用户应当注意在自己的开发环境中测试和调试程序,以确保理解程序的所有部分和逻辑。

客户端代码 #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <Winsock2.h> #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif #pragma comment(lib,"ws2_32.lib") int main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return -1; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return -1; } SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 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); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); send(sockClient, "hello\0", strlen("hello") + 1, 0); char recvBuf[50]; recv(sockClient, recvBuf, 50, 0); printf("%s\n", recvBuf); closesocket(sockClient); WSACleanup(); return 0;} 服务器端:#define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <Winsock2.h> #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif #pragma comment(lib,"ws2_32.lib") int main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return 1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { WSACleanup(); return 1; } SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); int optval = 1; setsockopt(sockSrv, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval)); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while (1) { SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len); char sendBuf[50]; printf(sendBuf, "Welcome %s to here!", inet_ntoa(addrClient.sin_addr)); send(sockConn, sendBuf, strlen(sendBuf) + 1, MSG_NOSIGNAL); char recvBuf[50]; recv(sockConn, recvBuf, 50, 0); printf("%s\n", recvBuf); closesocket(sockConn); } WSACleanup(); return 0;} 如何修改代码改成可以一直聊天的 不要预输入进去的 要我自己在客户端进行打字操作

2023-06-06 上传

#include<stdio.h> #include<stdlib.h> #include<WinSock2.h> //WindowsSocket编程头文件 #include<iostream> #include<cstring> #pragma comment(lib,"ws2_32.lib")//链接ws2_32.lib库文件到此项目中 using namespace std; //================全局常量================== //创建缓冲区 const int BUF_SIZE = 2048; //================全局变量================== SOCKET sockSer, sockCli; SOCKADDR_IN addrSer, addrCli; //address int naddr = sizeof(SOCKADDR_IN); char sendbuf[BUF_SIZE]; char inputbuf[BUF_SIZE]; char recvbuf[BUF_SIZE]; //================函数声明================== int main() { cout << "服务器启动" << endl; //加载socket库 WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2),&wsadata) != 0) { //输出出错信息 cout << "载入socket库失败!" << endl; system("pause"); return 0; } else { cout << "载入socket库成功!" << endl; } //创建Socket; sockSer = socket(AF_INET, SOCK_STREAM, 0); //描述协议族,INET属于ipv4; //sock_stream创建套接字类型:tcp; //0不指定协议,常用的协议有tcp、udp等 //初始化地址包 addrSer.sin_addr.s_addr = inet_addr("127.168.43.54"); addrSer.sin_family = AF_INET; addrSer.sin_port = htons(2500); //绑定Socket(bind) bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR)); //强制将SOCKADDR_INET转化成SOCKEADDR //监听 while (true) { cout << "开始连接!" << endl; //监听连接请求; listen(sockSer,5); //等待连接最大数:5 //接受连接 sockCli=accept(sockSer, (SOCKADDR*)&addrCli, &naddr); if (sockCli != INVALID_SOCKET) { while (true) { cout << "连接成功" << endl; cout << "请输入要发送给客户端的信息:" << endl; cin >> sendbuf; send(sockCli, sendbuf, sizeof(sendbuf), 0); //strcpy(sendbuf, "hello"); //send(sockCli, sendbuf, sizeof(sendbuf), 0); //接收客户端发来信息 recv(sockCli, recvbuf, sizeof(recvbuf), 0); cout << "客户端发来的信息:" << recvbuf << endl; } } else { cout << "连接失败!" << endl; } } closesocket(sockSer); closesocket(sockCli); return 0; } 运行后一直显示连接失败,是为啥

2023-06-03 上传