1.檔案傳輸
通過建立伺服器用戶端串連,進行檔案傳輸。由用戶端輸入一個檔案名稱,伺服器搜素,尋找成功後,向用戶端傳輸資料。用戶端接受在目前的目錄下建立檔案。
// hdksjfkl.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#include "iostream"#define MAXSTRINGSIZE 9000using namespace std;#pragma comment (lib,"ws2_32.lib")//擷取本機IP in_addr getHostName(void) { char host_name[255]; //擷取本地主機名稱 if (gethostname(host_name, sizeof(host_name)) == SOCKET_ERROR) { cout<<"Error %d when getting local host name."<<WSAGetLastError(); Sleep(3000); exit(-1); } //從主機名稱資料庫中得到對應的“IP” struct hostent *phe = gethostbyname(host_name); if (phe == 0) { cout<<"Yow! Bad host lookup."; Sleep(3000); exit(-1); } struct in_addr addr; memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr)); return addr; } //啟動伺服器 SOCKET StartServer(void) { //建立通訊端 SOCKET serverSocket; if((serverSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){ cout<<"建立通訊端失敗。"; Sleep(3000); exit(-1); } short port=1986; struct sockaddr_in serverAddress; //初始化指定的記憶體地區 memset(&serverAddress,0,sizeof(sockaddr_in)); serverAddress.sin_family=AF_INET; serverAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(port); //綁定 if(bind(serverSocket,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR){ cout<<"通訊端綁定到連接埠失敗。連接埠:"<<port; Sleep(3000); exit(-1); } //進入偵聽狀態 if(listen(serverSocket,SOMAXCONN)==SOCKET_ERROR){ cout<<"偵聽失敗。"; Sleep(3000); exit(-1); } //擷取伺服器IP struct in_addr addr = getHostName(); cout<<"Server "<<inet_ntoa(addr)<<" : "<<port<<" is listening......"<<endl; return serverSocket; } //接收用戶端串連 SOCKET ReceiveConnect(SOCKET &serverSocket) { char SendBuffer[80] = {0};int bytes; SOCKET clientSocket;//用來和用戶端通訊的通訊端 struct sockaddr_in clientAddress;//用來和用戶端通訊的通訊端地址 memset(&clientAddress,0,sizeof(clientAddress));//初始化存放用戶端資訊的記憶體 int addrlen = sizeof(clientAddress); //接受串連 if((clientSocket=accept(serverSocket,(sockaddr*)&clientAddress,&addrlen))==INVALID_SOCKET){ cout<<"接受用戶端串連失敗。"; Sleep(3000); exit(-1); } cout<<"Accept connection from "<<inet_ntoa(clientAddress.sin_addr)<<endl;sprintf(SendBuffer,"200 welcome\r\n"); //向用戶端發送歡迎訊息bytes = send(clientSocket,SendBuffer,strlen(SendBuffer),0); return clientSocket; } void sendfile(SOCKET &serverSocket){while(1){//接受用戶端命令並調用處理函數FILE * fp = NULL;char buf[30];char senmm[10];memset(senmm,0,sizeof(senmm));char sendbuf[500];memset(sendbuf,1,sizeof(sendbuf));char maxbuf[500];memset(maxbuf,1,sizeof(maxbuf));char sendmsg[50];memset(sendmsg,0,sizeof(sendmsg));SOCKET clientSocket = ReceiveConnect(serverSocket);do {memset(buf,1,sizeof(buf));int bytes = 0;if((bytes = recv(clientSocket,buf,strlen(buf)+1,0)) ==SOCKET_ERROR){sprintf(sendmsg,"接收資料失敗");send(clientSocket,sendmsg,strlen(sendmsg),0);break;}if((fp = fopen(buf,"r")) == NULL){sprintf(senmm,"檔案名稱錯誤");send(clientSocket,senmm,strlen(senmm)+1,0);printf("用戶端發來的檔案名稱沒有\n");//printf("%d位元組\n",bytes);}else{sprintf(senmm,"250");send(clientSocket,senmm, strlen(senmm) + 1,0);printf("客戶機發來檔案下載請求,檔案名稱如下%s\n",buf);break;Sleep(3000);}}while(1);Sleep(3000);char MMMM[1000];MMMM[0] = '\0';while(fgets(maxbuf,80,fp) != NULL){//迴圈讀取檔案並通過h_NewSocket發送到用戶端printf("%s\n",maxbuf);//sprintf(sendbuf,"%s",maxbuf);strcat(MMMM,maxbuf);//send(clientSocket,maxbuf,strlen(maxbuf) + 1,0);//printf(".");//*/printf("%s",sendbuf);}fclose(fp);printf("%s",MMMM);send(clientSocket,MMMM,strlen(MMMM) + 1,0);//sprintf(senmm,"266");//send(clientSocket,senmm,strlen(senmm) + 1,0);closesocket(clientSocket);}}int main(int argc, char* argv[]){WSADATA wsa;if(WSAStartup(MAKEWORD(2,2),&wsa) != 0){printf("通訊端初始化失敗!!\n");Sleep(3000);exit(-1);}SOCKET serverSocket = StartServer();sendfile(serverSocket);return 0;}
以上是伺服器段的代碼。
// hdksjfklclien.cpp : Defines the entry point for the console application.//#include "stdafx.h" #include <windows.h> #include <process.h> #include <iostream> #include "string.h"using namespace std; #pragma comment(lib,"ws2_32.lib") //接收資料 void Receive(SOCKET socket) { char buf[2096]; int bytes; if((bytes=recv(socket,buf,sizeof(buf),0))==SOCKET_ERROR){ printf("接收資料失敗!\n"); exit(-1); } buf[bytes]='\0'; cout<<buf<<endl; } //擷取伺服器IP unsigned long GetServerIP(void) { //把字串的IP地址轉化為u_long char ipStr[20]; //用第二個參數填充第一個參數所指的記憶體,填充的長度為第三個參數的大小 memset(ipStr,0,sizeof(ipStr)); // cout<<"請輸入你要連結的伺服器IP:"; // cin>>ipStr; strcpy(ipStr,"127.0.0.1"); unsigned long ip; if((ip=inet_addr(ipStr))==INADDR_NONE){ cout<<"不合法的IP地址:"; Sleep(3000); exit(-1); } return ip; } //發送資料 char path[80] = {'0'};void SendMsg(SOCKET &sock) { printf("請輸入要下載的檔案名稱\n");scanf("%s",path);printf("%d\n",strlen(path)); if(send(sock,path,strlen(path)+1,0)==SOCKET_ERROR){ cout<<"發送資料失敗。"; exit(-1); } cout<<"發送資料是"<<path<<endl;} //連結的伺服器 void CConnect(SOCKET &sock) { unsigned long ip=GetServerIP(); //把連接埠號碼轉化成整數 short port=1986; cout<<"Connecting to "<<inet_ntoa(*(in_addr*)&ip)<<" : "<<port<<endl; struct sockaddr_in serverAddress; memset(&serverAddress,0,sizeof(sockaddr_in)); serverAddress.sin_family=AF_INET; serverAddress.sin_addr.S_un.S_addr= ip; serverAddress.sin_port = htons(port); //建立和伺服器的串連 if(connect(sock,(sockaddr*)&serverAddress,sizeof(serverAddress))==SOCKET_ERROR){ cout<<"建立串連失敗:"<<WSAGetLastError(); Sleep(3000); exit(-1); } } int main(int argc, char* argv[]){WSADATA wsa; //初始化通訊端DLL if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){ cout<<"通訊端初始化失敗!"; Sleep(3000); exit(-1); } //建立通訊端 SOCKET sock; if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){ cout<<"建立通訊端失敗。"; exit(-1); } CConnect(sock);//連結的伺服器 Receive(sock);char buf[10];while(1){if((strncmp(buf,"250",strlen("250") + 1) == 0))break;SendMsg(sock);recv(sock,buf,strlen(buf) + 1,0);}FILE *fp;char recvbuf[1000];memset(recvbuf,1,sizeof(recvbuf));if((fp = fopen(path,"w+")) == NULL){printf("本地開啟檔案錯誤\n");return 0;}//int bytee = 0;//printf("%s\n",recvbuf); recv(sock,recvbuf,sizeof(recvbuf),0); printf("%s",recvbuf);fprintf(fp,recvbuf);fclose(fp);closesocket(sock);WSACleanup();printf("檔案接收完畢\n");return 0;}
以上是用戶端的代碼。