c/s架构的网络通讯程序:功能包括拨号,发消息,传文件

来源:互联网 发布:派拉软件 编辑:程序博客网 时间:2024/05/21 04:26

功能描述:

客户端:

1.拨号,输入IP,连接服务器

2.可以选择接收文件

(1)等待服务器的发送

(2)接收待传文件的名称

(3)是否修改该文件的名称

(4)在该客户端的文件夹下查看传送的文件

3.可以选择发送消息,发送“exit”即告诉服务器停止发送消息

4.停止通讯

服务器端:

1.显示连接客户端的IP和端口号

2.接收传文件命令

(1)输入想传送的文件名(相对路径和绝对路径都行)

(2)等待客户端的准备好

(3)传送文件

3.接收发送消息的命令,遇到“exit”即关闭该功能

4.停止通讯

note:

(1)发送消息的功能并没有实现聊天的功能。传文件和发消息都是单向的。可以进一步修改。

(2)由于采用二进制读写文件,所以可以传输任意类型,不受格式的限制,如.txt,.mp3,.mp4,.pptx,...都可以

prompt:以下代码环境为VS2015,不同环境请适当修改。传文件采用结尾加了标志位,0代表文件还在传送,1代表已经出传送完毕,需要控制缓冲区的长度,来加报头,去报头。


Sever代码:

// server.cpp : 定义控制台应用程序的入口点。//#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#endif#include <Windows.h>#include <WinSock2.h>#include <WS2tcpip.h>#include <IPHlpApi.h>#include <cstdio>#include <io.h>#pragma comment (lib, "Ws2_32.lib")#define DEFAULT_PORT "27015"#define DEFAULT_BUFLEN 512int main(){int iResult, iSendResult;WSADATA wsaData;struct addrinfo *result = NULL, *ptr = NULL, hints;char temp[DEFAULT_BUFLEN];char file_name[DEFAULT_BUFLEN];// Initialize WinsockiResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed with error: %d\n", iResult);return 1;}ZeroMemory(&hints, sizeof(hints));hints.ai_family = AF_INET;hints.ai_socktype = SOCK_STREAM;hints.ai_protocol = IPPROTO_TCP;hints.ai_flags = AI_PASSIVE; // caller to bind // Resolve the server address and portiResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);if (iResult != 0) {printf("getaddrinfo failed with error: %d\n", iResult);WSACleanup();return 1;}// create a socket for serverSOCKET ListenSocket = INVALID_SOCKET;ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);if (ListenSocket == INVALID_SOCKET){printf("server failed at socket(): %ld\n", WSAGetLastError());freeaddrinfo(result);WSACleanup();return 1;}// bind a socketiResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);if (iResult == SOCKET_ERROR){printf("server bind faild: %ld\n", WSAGetLastError());freeaddrinfo(result);closesocket(ListenSocket);WSACleanup();return 1;}freeaddrinfo(result); // once bind, no longer needed  // listen on a socketif (listen(ListenSocket, SOMAXCONN)){printf("server listen socket failed %ld\n", WSAGetLastError());closesocket(ListenSocket);WSACleanup();return 1;}// accept a connectionsockaddr_in client_addr;//int nlen;SOCKET ClientSocket = INVALID_SOCKET;//ClientSocket = accept(ListenSocket, NULL, NULL);sockaddr_in clientAddr;int addrlen = sizeof(clientAddr);ClientSocket = accept(ListenSocket, (sockaddr*)&clientAddr, &addrlen);if (ClientSocket == INVALID_SOCKET){printf("server accept failed: %ld\n", WSAGetLastError());closesocket(ListenSocket);WSACleanup();return 1;}//char *ip = inet_ntoa(client_addr.sin_addr);//printf("establish connection to server %s\n", ip);// no longer needclosesocket(ListenSocket);printf("Connect a client\nShow client ip and socket:%s, %d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));while (1) {while (1) {iResult = recv(ClientSocket, temp, DEFAULT_BUFLEN, 0);if (iResult > 0) {temp[iResult] = '\0';printf("\n%s command received.\n\n", temp);break;}}if (strcmp(temp, "file") == 0) {// file operation and send dataprintf("input the file you want to transfer\n");scanf_s("%s", temp, DEFAULT_BUFLEN);FILE * fp;errno_t err;err = fopen_s(&fp, temp, "rb"); // binary mode for readif (err != 0){printf("open file %s failed\n", temp);return -1;}while (1) {if (send(ClientSocket, temp, (int)strlen(temp), 0) > 0) {printf("Wait the client to prepare well...\n");break;}//Sleep(1000);}memset(temp, 0, DEFAULT_BUFLEN);while (1) {iResult = recv(ClientSocket, temp, DEFAULT_BUFLEN, 0);if (iResult > 0 && strcmp(temp,"ok") == 0) {printf("the client is well ready to receive the file\n");break;}}memset(temp, 0, DEFAULT_BUFLEN);int length = 0;while (1){length = fread(temp, sizeof(char), DEFAULT_BUFLEN - 1, fp);if (length == 0) {temp[length] = '1';//end flag is '1'if (send(ClientSocket, temp, length + 1, 0) < 0){printf("Send File: %s Failed\n");break;}break;} else {temp[length] = '0';if (send(ClientSocket, temp, length + 1, 0) < 0){printf("Send File: %s Failed\n");break;}memset(temp, 0, DEFAULT_BUFLEN);}}fclose(fp);printf("server file transfer success\n");}else if (strcmp(temp, "message") == 0) {while (1) {memset(temp, 0, DEFAULT_BUFLEN);iResult = recv(ClientSocket, temp, SOMAXCONN, 0);if (iResult > 0) {temp[iResult] = '\0';if (strcmp(temp, "exit") == 0) {break;}elseprintf("Receive data:%s\n", temp);memset(temp, 0, DEFAULT_BUFLEN);}}}else if (strcmp(temp, "exit") == 0) {printf("the client is disconnected\n");break;}}if (iResult == SOCKET_ERROR){printf("server shutdown failed %ld\n", WSAGetLastError());closesocket(ClientSocket);WSACleanup();return 1;}while (1);closesocket(ClientSocket);WSACleanup();return 0;}


client代码:

// client.cpp : 定义控制台应用程序的入口点。////prevent winsock.h (version 1.1)from being included by windows.h#ifndef WIN32_LEAN_AND_MEAN#define WIN32_LEAN_AND_MEAN#endif#include <Windows.h>#include <winsock2.h>#include <ws2tcpip.h>#include <iphlpapi.h> // after winsock2.h#include <cstdio>#include<iostream>#pragma comment (lib, "Ws2_32.lib")#pragma comment (lib, "Mswsock.lib")#pragma comment (lib, "AdvApi32.lib")#define DEFAULT_PORT "27015"#define DEFAULT_BUFLEN 512int main(){int iResult;WSADATA wsaData;struct addrinfo *result = NULL, *ptr = NULL, hints;char sendbuf[] = "this is a test for client";char recvbuf[DEFAULT_BUFLEN];int recvbuflen = DEFAULT_BUFLEN;char temp[DEFAULT_BUFLEN], file_name[DEFAULT_BUFLEN];printf("input ip address of server\n");scanf_s("%s", temp, DEFAULT_BUFLEN);// Initialize WinsockiResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != 0) {printf("WSAStartup failed with error: %d\n", iResult);return 1;}ZeroMemory(&hints, sizeof(hints));hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;hints.ai_protocol = IPPROTO_TCP;// resolve the server address and port, argv[1] is server nameiResult = getaddrinfo(temp, DEFAULT_PORT, &hints, &result);if (iResult != 0){printf("client get addrinfor fail: %d\n", iResult);WSACleanup(); // terminate use of WS2_32.dllreturn 1;}SOCKET ConnectSocket = INVALID_SOCKET;for (ptr = result; ptr != NULL; ptr = ptr->ai_next){// create a socket for clientConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);if (ConnectSocket == INVALID_SOCKET){printf("client socket failed with error %ld\n", WSAGetLastError());WSACleanup();return 1;}// connect to serveriResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);if (iResult == SOCKET_ERROR){closesocket(ConnectSocket);ConnectSocket = INVALID_SOCKET;// if fail try next address returned by getaddrinfocontinue;}break;}freeaddrinfo(result);if (ConnectSocket == INVALID_SOCKET){printf("client unable to connect to server\n");WSACleanup();return 1;}while (1) {//temp[DEFAULT_BUFLEN];printf("\nPlease input a command to run:1.\"file\" 2.\"message\" 3.\"exit\"\n");std::cin >> temp;iResult = send(ConnectSocket, temp, (int)strlen(temp), 0);if (iResult <= 0) {printf("The command is unuseful.\n");}if (strcmp(temp, "file") == 0) {printf("Wait a file from server...\n");//create fileFILE * fp;errno_t err;while (1) {iResult = recv(ConnectSocket, file_name, DEFAULT_BUFLEN, 0);if (iResult > 0)break;}file_name[iResult] = '\0';//receive data from serverprintf("\nprepare to receive :\n%s\n\n",file_name);printf("Do you want to change the received file name and position:\n1.yes 2.no\n");char input[100];scanf_s("%s", input, 100);if (strcmp(input,"yes") == 0) {scanf_s("%s", file_name, DEFAULT_BUFLEN);}err = fopen_s(&fp, file_name, "wb+"); // binary mode for readif (err != 0){printf("open file %s failed\n", file_name);return -1;}while (1) {if (send(ConnectSocket, "ok", (int)strlen("ok"), 0) > 0) {printf("ready to receive the file...\n");break;}}memset(temp, 0, DEFAULT_BUFLEN);int length = 0;while ((length = recv(ConnectSocket, temp, DEFAULT_BUFLEN, 0)) > 0){if (temp[length-1] == '1') {//识别文件的结尾break;}if (fwrite(temp, sizeof(char), length - 1, fp) < length - 1){printf("File: %s Write Failed\n", file_name);break;}memset(temp, 0, DEFAULT_BUFLEN);}printf("transmission done\n");fclose(fp);}else if (strcmp(temp, "message") == 0) {printf("\nIntput the \"exit\" to end the transformation.\n");while (1) {printf("input your message:\n");std::cin >> temp;if (strcmp(temp, "exit") == 0) {iResult = send(ConnectSocket, temp, (int)strlen(temp), 0);break;}iResult = send(ConnectSocket, temp, (int)strlen(temp), 0);if (iResult <= 0) {printf("The command is unuseful.\n");}}}else if (strcmp(temp, "exit") == 0) {printf("The transformation is over.\n");break;}}while (1);closesocket(ConnectSocket);WSACleanup();return 0;}



原创粉丝点击