赞
踩
实验要求:使服务器与多个客户端进行通信,同时接收多个客户端上传的文件。
服务端代码:
- #include"iostream"
- #include"afxmt.h"
- #include"process.h"
- #include"winsock2.h"
- #include"fstream"
- #include"WS2tcpip.h"
- #include"direct.h"
-
-
- #define PORT 65432
- #pragma comment(lib,"ws2_32.lib")
-
- using namespace std;
- struct fileMessage
- {
- char fileName[256];
- long int fileSize;
- };
-
-
- /*主程序和线程函数共用的全局变量定义*/
- char fname[128] = { 0 }; //发送给客户端的无路径信息的文件名
- ifstream inFile; //定义文件的输入流
- CMutex Section; //创建互斥对象
- void rdFile(void* par); //发送文件的线程函数声明
-
- /*主函数*/
-
- int main()
- {
- SOCKET sock_server; //定义监听套接字
- struct sockaddr_in addr;
- struct sockaddr_in client_addr; //存放本地地址和客户地址的变量
- SOCKET newsock; //储存accept()返回的套接字描述符
- /*初始化winsock DLL*/
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- cout << "加载winSock动态链接库失败!\n";
- return 0;
- }
-
- /*创建监听套接字*/
- if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- cout << "创建套接字失败!\n";
- WSACleanup();
- return 0;
- }
-
- /*绑定IP地址与端口*/
- memset((void*)&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(65432);
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(sock_server, (struct sockaddr*)&addr, sizeof(addr)) != 0)
- {
- cout << "绑定失败!\n";
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
- if (listen(sock_server, 5) != 0)
- {
- cout << "listen函数调用失败!\n";
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
- else
- {
- cout << "listenning.....\n";
- }
-
- /*接收客户连接请求*/
- int addr_len = sizeof(struct sockaddr_in);
- while (true)
- {
- newsock = accept(sock_server, (LPSOCKADDR)&client_addr, &addr_len);
- if (newsock != INVALID_SOCKET)
- {
- cout << "一个客户连接成功!" << endl;
- _beginthread(rdFile, 0, (LPVOID)newsock);
-
- }
- else
- {
- break;
- }
-
- }
-
- closesocket(newsock);
- closesocket(sock_server);
- WSACleanup();
- return 0;
-
- }
-
- void rdFile(void* par)
- {
- /*定义文件传输所需变量*/
- struct fileMessage fileMsg;
- SOCKET sock = (SOCKET)par;
- long int filelen;
- char filename[500] = "C:\\Users\\86152\\source\\repos\\textfile"; //指定文件的保存目录
- char ok[3] = "OK";
- char fileBuffer[1000]; //接收文件数据的缓冲区
- _mkdir(filename); //_mkdir()用于创建文件夹,其声明包含在direct.h中
-
- /*接收文件名及文件长度信息*/
- if ((filelen = recv(sock, (char*)&fileMsg, sizeof(fileMsg), 0)) <= 0)
- {
- cout << "未接收到文件名及文件长度!\n";
- closesocket(sock);
- WSACleanup();
- return;
- }
-
- filelen = ntohl(fileMsg.fileSize);
- strcat_s(filename, fileMsg.fileName);
- ofstream outFile(filename, ios::out | ios::binary); //创建文件对象
- if (!outFile.is_open())
- {
- cout << "Cannot open" << filename << endl;
- closesocket(sock);
- WSACleanup();
- return; //文件打开失败则退出
- }
- send(sock, ok, sizeof(ok), 0); //发送接收文件数据的确认信息
- int size = 0;
- do
- {
- size = recv(sock, fileBuffer, sizeof(fileBuffer), 0);
- if (size <= 0)break;
- outFile.write(fileBuffer, size);
- filelen -= size;
- } while (filelen > 0);
-
- if (filelen == 0)
- {
- cout << "Transfer finished!\n";
- }
- else
- {
- cout << "Transfer Failed!\n";
- }
- outFile.close();
- closesocket(sock);
-
- }
客户端代码:
- #include<iostream>
- #include"fstream"
- #include"winsock2.h"
- #include"WS2tcpip.h"
- #include"direct.h"
- #pragma comment(lib,"ws2_32.lib")
-
- using namespace std;
- struct fileMessage //定义存储文件信息的结构体
- {
- char fileName[256];
- long int fileSize;
-
- };
-
- int main()
- {
- /*定义网络连接的相关变量*/
- int sock_client; //定义套接字
- struct sockaddr_in server_addr; //用于存放服务器地址的变量
- int addr_len = sizeof(struct sockaddr_in); //地址长度
- /*初始化winsock DLL*/
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- cout << "加载winsock动态链接库失败!\n";
- return 0;
- }
-
- char filename[500]; //用于存储要传输的文件的文件路径
- cout << "输入要输入的文件路径:";
- cin.getline(filename, 500);
-
- /*创建套接字*/
- if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- cout << "创建套接字失败!\n";
- WSACleanup();
- return 0;
- }
-
- /*输入服务器IP地址及端口号*/
- char IP[20];
- // unsigned short port;
- in_addr a;
- cout << "请输入服务器IP地址:";
- cin >> IP;
- inet_pton(AF_INET, IP, &a);
- memset((void*)&server_addr, 0, addr_len);
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(65432);
- server_addr.sin_addr.s_addr = a.S_un.S_addr;
- if (connect(sock_client, (struct sockaddr*)&server_addr, addr_len) != 0)
- {
- cout << "连接失败!\n";
- closesocket(sock_client);
- WSACleanup();
- return 0;
- }
-
-
-
- char OK[3], fileBuffer[1000]; //定义接收“OK”的缓冲区和发送缓冲区
- struct fileMessage fileMsg; //定义保存文件名及文件长度的结构变量
- ifstream inFile(filename, ios::in | ios::binary); //定义文件对象并打开文件
- if (!inFile.is_open())
- {
- cout << "CAnnot open" << filename << endl;
- closesocket(sock_client);
- WSACleanup();
- return 0; //文件打开失败则退出
- }
-
- /*从文件路径中提取文件名保存到结构变量fileMsg中*/
- unsigned int size = strlen(filename);
- while (filename[size] != '\\' && size > 0)size--;
- strcpy_s(fileMsg.fileName, filename + size);
-
- /*获取文件长度并存入结构变量fileMsg中*/
- inFile.seekg(0, ios::end); //将文件的位置指针移到文件末尾
- size = inFile.tellg(); //获取当前文件位置指针值
- fileMsg.fileSize = htonl(size); //将文件长度存入结构变量fileMeg
- send(sock_client, (char*)&fileMsg, sizeof(fileMsg), 0);//发送fileMeg
- if (recv(sock_client, OK, sizeof(OK), 0) <= 0) //接收对方发来的OK信息
- {
- cout << "接收OK失败,程序退出!\n";
- closesocket(sock_client);
- WSACleanup();
- return 0;
-
- }
- if (strcmp(OK, "OK") == 0) //如果对方已准备好接收则发送文件内容
- {
- inFile.seekg(0, ios::beg); //将文件的位置指针返回到文件头
- while (!inFile.eof())
- {
- inFile.read(fileBuffer, sizeof(fileBuffer));
- size = inFile.gcount(); //读取实际读取的字节数
- send(sock_client, fileBuffer, size, 0);
-
- }
- cout << "File Transfer Finished!\n";
- inFile.close(); //关闭文件
- }
- else
- {
- cout << "对方无法接收文件!";
- }
- closesocket(sock_client);
- WSACleanup();
- return 0;
-
-
- }
实现效果:
实验要求:服务器同时向多个客户端发送文件
- #include<iostream>
- #include"fstream"
- #include"winsock2.h"
- #pragma comment(lib,"ws2_32.lib")
-
- using namespace std;
- struct fileMessage //定义存储文件信息的结构体
- {
- char fileName[256];
- long int fileSize;
-
- };
-
- int main()
- {
- SOCKET sock_server; //定义监听套接字
- struct sockaddr_in addr;
- struct sockaddr_in client_addr; //存放本地地址和客户地址的变量
- SOCKET newsock; //储存accept()返回的套接字描述符
- /*初始化winsock DLL*/
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
- {
- cout << "加载winSock动态链接库失败!\n";
- return 0;
- }
-
- char filename[500]; //用于存储要传输的文件的文件路径
- cout << "输入要输入的文件路径:";
- cin.getline(filename, 500);
-
-
- /*创建监听套接字*/
- if ((sock_server=socket(AF_INET,SOCK_STREAM,0))<0)
- {
- cout << "创建套接字失败!\n";
- WSACleanup();
- return 0;
- }
-
- /*绑定IP地址与端口*/
- memset((void*)&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(65432);
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(sock_server,(struct sockaddr*)&addr,sizeof(addr))!=0)
- {
- cout << "绑定失败!\n";
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
- if (listen(sock_server,5)!=0)
- {
- cout << "listen函数调用失败!\n";
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
- else
- {
- cout << "listenning.....\n";
- }
-
- /*接收客户连接请求*/
- int addr_len = sizeof(struct sockaddr_in);
- if ((newsock=accept(sock_server,(struct sockaddr*)&client_addr,&addr_len))==INVALID_SOCKET)
- {
- cout << "accept函数调用失败!\n";
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
- cout << "客户连接成功!" << endl;
- char OK[3], fileBuffer[1000]; //定义接收“OK”的缓冲区和发送缓冲区
- struct fileMessage fileMsg; //定义保存文件名及文件长度的结构变量
- ifstream inFile(filename, ios::in | ios::binary); //定义文件对象并打开文件
- if (!inFile.is_open())
- {
- cout << "CAnnot open" << filename << endl;
- closesocket(newsock);
- closesocket(sock_server);
- WSACleanup();
- return 0; //文件打开失败则退出
- }
-
- /*从文件路径中提取文件名保存到结构变量fileMsg中*/
- unsigned int size = strlen(filename);
- while (filename[size] !='\\' && size> 0)size--;
- strcpy_s(fileMsg.fileName, filename + size);
-
- /*获取文件长度并存入结构变量fileMsg中*/
- inFile.seekg(0, ios::end); //将文件的位置指针移到文件末尾
- size = inFile.tellg(); //获取当前文件位置指针值
- fileMsg.fileSize = htonl(size); //将文件长度存入结构变量fileMeg
- send(newsock, (char*)&fileMsg, sizeof(fileMsg), 0);//发送fileMeg
- if (recv(newsock,OK,sizeof(OK),0)<=0) //接收对方发来的OK信息
- {
- cout << "接收OK失败,程序退出!\n";
- closesocket(newsock);
- closesocket(sock_server);
- WSACleanup();
- return 0;
-
- }
- if (strcmp(OK,"OK")==0) //如果对方已准备好接收则发送文件内容
- {
- inFile.seekg(0, ios::beg); //将文件的位置指针返回到文件头
- while (!inFile.eof())
- {
- inFile.read(fileBuffer, sizeof(fileBuffer));
- size = inFile.gcount(); //读取实际读取的字节数
- send(newsock, fileBuffer, size, 0);
-
- }
- cout << "File Transfer Finished!\n";
- inFile.close(); //关闭文件
- }
- else
- {
- cout << "对方无法接收文件!";
- }
- closesocket(newsock);
- closesocket(sock_server);
- WSACleanup();
- return 0;
- }
客户端代码:
- #include<iostream>
- #include"fstream"
- #include"winsock2.h"
- #include"WS2tcpip.h"
- #include"direct.h"
- #pragma comment(lib,"ws2_32.lib")
-
- using namespace std;
- struct fileMessage
- {
- char fileName[256];
- long int fileSize;
- };
-
- int main()
- {
- /*定义网络连接的相关变量*/
- int sock_client; //定义套接字
- struct sockaddr_in server_addr; //用于存放服务器地址的变量
- int addr_len = sizeof(struct sockaddr_in); //地址长度
- /*初始化winsock DLL*/
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
- {
- cout << "加载winsock动态链接库失败!\n";
- return 0;
- }
-
- /*创建套接字*/
- if ((sock_client=socket(AF_INET,SOCK_STREAM,0))<0)
- {
- cout << "创建套接字失败!\n";
- WSACleanup();
- return 0;
- }
-
- /*输入服务器IP地址及端口号*/
- char IP[20];
- // unsigned short port;
- in_addr a;
- cout << "请输入服务器IP地址:";
- cin >> IP;
- inet_pton(AF_INET, IP, &a);
- memset((void*)&server_addr, 0, addr_len);
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(65432);
- server_addr.sin_addr.s_addr = a.S_un.S_addr;
- if (connect(sock_client, (struct sockaddr*)&server_addr, addr_len) != 0)
- {
- cout << "连接失败!\n";
- closesocket(sock_client);
- WSACleanup();
- return 0;
- }
-
- /*定义文件传输所需变量*/
- struct fileMessage fileMsg;
- long int filelen;
- char filename[500] = "D:\\BaiduNetdiskDownload\\visualstudio\\vsfile\\transferfileclient"; //指定文件的保存目录
- char ok[3] = "OK";
- char fileBuffer[1000]; //接收文件数据的缓冲区
- _mkdir(filename); //_mkdir()用于创建文件夹,其声明包含在direct.h中
-
- /*接收文件名及文件长度信息*/
- if ((filelen=recv(sock_client,(char*)&fileMsg,sizeof(fileMsg),0))<=0)
- {
- cout << "未接收到文件名及文件长度!\n";
- closesocket(sock_client);
- WSACleanup();
- return 0;
- }
-
- filelen = ntohl(fileMsg.fileSize);
- strcat_s(filename, fileMsg.fileName);
- ofstream outFile(filename, ios::out | ios::binary); //创建文件对象
- if (!outFile.is_open())
- {
- cout << "Cannot open" << filename << endl;
- closesocket(sock_client);
- WSACleanup();
- return 0; //文件打开失败则退出
- }
- send(sock_client, ok, sizeof(ok), 0); //发送接收文件数据的确认信息
- int size = 0;
- do
- {
- size = recv(sock_client, fileBuffer, sizeof(fileBuffer), 0);
- if (size <= 0)break;
- outFile.write(fileBuffer, size);
- filelen -= size;
- } while (filelen>0);
-
- if (filelen==0)
- {
- cout << "Transfer finished!\n";
- }
- else
- {
- cout << "Transfer Failed!\n";
- }
- outFile.close();
- closesocket(sock_client);
- WSACleanup();
- return 0;
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。