計算機網絡實驗一 完整TCP/UDP協議 服務端客戶端代碼

實驗報告

完整代碼如下:

注:pch.h是Visual Studio需要的預編譯頭,可以刪除

// UDP_server.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>

#pragma comment(lib,"ws2_32.lib")

#define buffer_length 512   //接收緩存大小
#define packet_size 53000
using namespace std;
void main()
{
	WSADATA wsadata;
	SOCKET sSocket;

	int ilen;
	int irecv;
	char recv_buf[buffer_length];  //定義接收緩存

	//服務器和客戶SOCKETADDR地址結構
	struct sockaddr_in seradd, cliadd;


	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		printf("failed to load winsocket\n");
		return;
	}


	sSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (sSocket == INVALID_SOCKET)
	{
		printf("socket() failed:%d\n", WSAGetLastError());
		return;
	}

	//初始化服務器SOCKET地址結構
	seradd.sin_family = AF_INET;
	seradd.sin_port = htons(8000);
	//seradd.sin_addr.s_addr=htonl(INADDR_ANY);
	seradd.sin_addr.s_addr = inet_addr("192.168.43.118");

	if (bind(sSocket, (LPSOCKADDR)&seradd, sizeof(seradd)) == SOCKET_ERROR)
	{
		printf("地址綁定時出錯:%d\n", WSAGetLastError());
		return;
	}

	ilen = sizeof(cliadd);

	//初始化接收緩衝區
	memset(recv_buf, 0, sizeof(recv_buf));

	while (1)
	{
		cout << "初始化OK!" << endl;
		//在此函數中cli爲傳出參數	
		irecv = recvfrom(sSocket, recv_buf, buffer_length, 0, (struct sockaddr*)&cliadd, &ilen);
		if (irecv == SOCKET_ERROR)
		{
			printf("接收出錯%d\n", WSAGetLastError());
			return;
		}
		else if (irecv == 0)
			break;
		else
		{
			printf("%s--", recv_buf);
			printf("Server received from Client ip:[%s],port:[%d]\n", inet_ntoa(cliadd.sin_addr), ntohs(cliadd.sin_port));
		}
	
		FILE *fp;
		char file_name[20];
		//char sendData[400000];
		int ret;
		cout << "------------------------------SENDING...------------------------------" << endl;
		cout << "Please input the filename:" << endl;
		cin >> file_name;
		//傳送文件名
		sendto(sSocket, file_name, strlen(file_name), 0, (sockaddr *)&cliadd, ilen);
		if (!(fp = fopen(file_name, "rb")))
		{
			cout << "File " << file_name << " can't open" << endl;
			continue;
		}
		int length;
		fseek(fp, 0, SEEK_END);
		length = ftell(fp);
		cout <<"length"<< length << endl;
		rewind(fp);
		char *sendData = (char*)malloc(length);
		memset(sendData, 0x00,length);
		//傳送長度
		char leng_char[20];
		itoa(length, leng_char, 10);
		sendto(sSocket,leng_char, strlen(leng_char), 0, (sockaddr *)&cliadd, ilen);
		//傳送文件
		int length_read;
		length_read = fread(sendData, sizeof(char), length, fp);
		cout << "length_read=" << length_read << endl;
		char *dataptr = sendData;
		ret = sendto(sSocket, dataptr, packet_size, 0, (sockaddr *)&cliadd, ilen);
		int i = 1;
		int send_no = (length / packet_size);
		while (i==send_no||i<send_no)
		{			
			//cout << "length=" << length << endl;
			//cout << sendData << endl;		
			dataptr += packet_size;
			Sleep(50);
			if (ret == SOCKET_ERROR || ret == 0)
			{
				cout << ret << endl;
				cout << "wrong" << endl;
				return ;
			}
			cout <<i<< "send successful!" << endl;
			if (i < length/packet_size) {
				ret = sendto(sSocket, dataptr, packet_size, 0, (sockaddr *)&cliadd, ilen);
			}
			else {
				cout << "最後一段數據" << (length % packet_size) << endl;
				ret = sendto(sSocket, dataptr,length%packet_size , 0, (sockaddr *)&cliadd, ilen);
			}
			i++;
		}
		cout << i << "send successful!" << endl;
		fclose(fp);
		//表明傳輸時間,對象
		SYSTEMTIME st;
		GetLocalTime(&st);
		cout << "Linking Time:" << st.wYear << "/" << st.wMonth << "/" << st.wDay << "  " << st.wHour << ":" << st.wMinute << endl;
		//cout << "Client:" << inet_ntoa(cliadd.sin_addr) << ":" << ntohs(cliadd.sin_port) << " Connection!" << endl;
		cout << "----------------------------------------------------------------------" << endl;
	}
	closesocket(sSocket);
	WSACleanup();
}
// Client(UDP).cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>
#include<winsock2.h>
#include <stdio.h>

#define data_buffer  20   //發送緩存大小
#define BUF_MAXLEN 53000
#define MAX_NAME 20

#pragma comment(lib,"ws2_32.lib")
using namespace std;

void main()
{
	WSADATA wsadata;
	SOCKET sclient;


	//服務器地址、端口號
	const char * serip = "192.168.43.118";
	int  Seriport = 8000;

	char ch[100];
	//字符數組初始化
	memset(ch, 0, sizeof(ch));

	//要發送給服務器的數據
	char send_buf[] = "hello,I am a client.";

	//定義接收緩存
	char recv_buf[data_buffer];
	//初始化接收緩存
	memset(recv_buf, 0, sizeof(recv_buf));


	//發送數據大小
	int isend;


	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		printf("failed to load winsock\n");
		return;
	}

	//服務器端的SOCKETADDR地址結構
	struct sockaddr_in seradd;
	// 服務器SOCKET地址結構初始化
	seradd.sin_family = AF_INET;
	seradd.sin_port = htons(Seriport);
	seradd.sin_addr.s_addr = inet_addr(serip);

	int serlen = sizeof(seradd);


	sclient = socket(AF_INET, SOCK_DGRAM, 0);
	if (sclient == INVALID_SOCKET)
	{
		printf("build socket failed!\n");
		return;
	}


	//無連接不需要進行地址與套接字的綁定,直接發送數據即可
	isend = sendto(sclient, send_buf, sizeof(send_buf), 0, (struct sockaddr *)&seradd, sizeof(seradd));
	if (isend != 0 && isend != SOCKET_ERROR)
	{
		printf("客戶所發的數據爲:%s, 字節數爲:%d\n", send_buf, isend);

	}
	else return;

	//while (1)
	//{
	//	cin >> ch;
	//	getchar();
	//	sendto(sclient,ch, sizeof(ch), 0, (struct sockaddr*)&seradd, sizeof(seradd));
	//}
	while(true)
    {
		int ret;
		//char recvData[BUF_MAXLEN];
		char file_name[MAX_NAME];
		//接收文件名
		ret = recvfrom(sclient, file_name, MAX_NAME, 0, (sockaddr *)&seradd, &serlen);
		file_name[ret] = '\0';
		//接收文件長度
		ret = recvfrom(sclient, recv_buf, data_buffer, 0, (sockaddr*)&seradd, &serlen);
		recv_buf[ret] = '\0';
		int length;
		sscanf(recv_buf, "%d", &length);
		cout<<"-----------------------------RECEIVING...-----------------------------"<<endl;
		//打開文件
		char *recvData = (char*)malloc(length);
		FILE * fp;
		if (!(fp = fopen(file_name, "wb")))
		{
		    cout<<"File "<<file_name<<" can't open"<<endl;
			return;
		}
		memset(recvData, 0, length);

		char *dataptr = recvData;

		int file_len = 0;//接收文件
		file_len = recvfrom(sclient, dataptr, BUF_MAXLEN, 0, (sockaddr *)&seradd, &serlen);
		int i = 1;
		while(i<length/ BUF_MAXLEN||i==length/BUF_MAXLEN)
		{
		    if (file_len == INVALID_SOCKET || file_len == 0)
		    {
		        cout << "Receive Error" << endl;
		        return ;
		    }
			dataptr += BUF_MAXLEN;
			file_len = recvfrom(sclient, dataptr, BUF_MAXLEN, 0, (sockaddr *)&seradd, &serlen);
			i++;
		}
		ret = fwrite(recvData, sizeof(char), length, fp);//寫文件

		cout<<"Receive "<<file_name<<" Successful!"<<endl;
		//表明傳輸時間,對象
		SYSTEMTIME st;
		GetLocalTime(&st);
		cout<<"Linking Time:"<<st.wYear<<"/"<<st.wMonth<<"/"<<st.wDay<<"  "<<st.wHour<<":"<<st.wMinute<<endl;
		cout<<"Server "<<inet_ntoa(seradd.sin_addr)<<":"<<ntohs(seradd.sin_port)<< " Connection!" << endl;
		cout<<"----------------------------------------------------------------------"<<endl;
        cout<<endl;
	};
	closesocket(sclient);
	WSACleanup();
}

// TCP_server.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>
#include <Winsock2.h>
//#include<stdlib.h>
#define packet_size 512
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void main()
{

	WSADATA wsaData;
	SOCKET oldSocket, newSocket;
	int i = 0;

	//客戶SOCKETAddr地址結構
	int iLen = 0;

	//接收的數據長度
	int irecvLen = 0;


	//接收來自用戶的信息,即接收緩存
	char recvBuf[512];

	//客戶和服務器的SOCKETAddr地址結構
	struct sockaddr_in serAddr, clientAddr;


	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		cout << "failed to load winsock" << endl;
		return;
	}


	cout << "server waiting" << endl;
	cout << "---------------" << endl;

	//創建服務器端幀聽SOCKET
	oldSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (oldSocket == INVALID_SOCKET)
	{
		cout << "socket() failed:" << WSAGetLastError() << endl;
		return;
	}


	//以下是建立服務器端的SOCKET地址結構
	serAddr.sin_family = AF_INET;
	serAddr.sin_port = htons(5050);
	serAddr.sin_addr.s_addr = inet_addr("192.168.43.118");

	if (bind(oldSocket, (LPSOCKADDR)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		cout << "bind() failed:" << WSAGetLastError() << endl;
		return;
	}

	//進入偵聽狀態
	if (listen(oldSocket, 5) == SOCKET_ERROR)
	{
		cout << "listen() failed:" << WSAGetLastError() << endl;
		return;
	}

	//接收客戶端的連接
	iLen = sizeof(clientAddr);
	newSocket = accept(oldSocket, (struct sockaddr*)&clientAddr, &iLen);//產生一個新的SOCKET

	if (newSocket == INVALID_SOCKET)
	{
		cout << "accept() failed:" << WSAGetLastError() << endl;//
		return;
	}

	//進入一個無限循環,等待客戶發送數據
	while (1)
	{
		i++;
		//服務器初始化接收緩衝區
		memset(recvBuf, 0, 512);
		irecvLen = recv(newSocket, recvBuf, sizeof(recvBuf), 0);
		if (irecvLen == SOCKET_ERROR)
		{
			cout << "rcv() failed:" << WSAGetLastError() << endl;
			break;
		}
		else if (irecvLen == 0)
			break;
		else {
			cout << "---服務器接收的內容爲---" << recvBuf << endl;
		}
		if (strcmp(recvBuf, "quit") == 0)
		{
			FILE *fp;
			char file_name[20]="姚靜.avi";
			int ret;
			cout << "------------------------------SENDING...------------------------------" << endl;
			//cout << "Please input the filename:" << endl;
			//cin >> file_name;
			////傳送文件名
			//sendto(newSocket, file_name, strlen(file_name), 0, (sockaddr *)&clientAddr, iLen);
			if (!(fp = fopen(file_name, "rb")))
			{
				cout << "File " << file_name << " can't open" << endl;
				return;
			}
			int length;
			fseek(fp, 0, SEEK_END);
			length = ftell(fp);
			cout << "length" << length << endl;
			rewind(fp);
			char *sendData = (char*)malloc(length);
			memset(sendData, 0x00, length);
			//傳送長度
			char leng_char[20];
			itoa(length, leng_char, 10);
			cout << "傳送長度de長度" << strlen(leng_char) << endl;
			//sendto(newSocket, leng_char, strlen(leng_char), 0, (sockaddr *)&clientAddr, iLen);
			//傳送文件
			int length_read;
			length_read = fread(sendData, sizeof(char), length, fp);
			cout << "length_read=" << length_read << endl;
			char *dataptr = sendData;
			ret = sendto(newSocket, dataptr, packet_size, 0, (sockaddr *)&clientAddr, iLen);
			//cout << dataptr << endl;
			int i = 1;
			int send_no = (length / packet_size);
			while ( i < send_no)
			{
				dataptr += packet_size;
				Sleep(5);
				if (ret == SOCKET_ERROR || ret == 0)
				{
					cout << ret << endl;
					cout << "wrong" << endl;
					return;
				}
				cout << i << "send successful!" << endl;
				if (i < length / packet_size) {
					ret = sendto(newSocket, dataptr, packet_size, 0, (sockaddr *)&clientAddr, iLen);
					//cout << dataptr << endl;
				}
				else {
					cout << "最後一段數據" << (length % packet_size) << endl;
					ret = sendto(newSocket, dataptr, length%packet_size, 0, (sockaddr *)&clientAddr, iLen);
					//cout << dataptr << endl;
				}
				i++;
			}
			cout << i << "send successful!" << endl;
			fclose(fp);
			//表明傳輸時間,對象
			SYSTEMTIME st;
			GetLocalTime(&st);
			cout << "Linking Time:" << st.wYear << "/" << st.wMonth << "/" << st.wDay << "  " << st.wHour << ":" << st.wMinute << endl;
			//cout << "Client:" << inet_ntoa(cliadd.sin_addr) << ":" << ntohs(cliadd.sin_port) << " Connection!" << endl;
			cout << "----------------------------------------------------------------------" << endl;
		}
	}
	
	
	closesocket(newSocket);
	closesocket(oldSocket);
	WSACleanup();
}

#include "pch.h"
#include<winsock2.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
//#include<stdio.h>
#define data_buffer1  512   //發送緩存大小
#define BUF_MAXLEN 512
#define MAX_NAME 512
#define DATA_BUFFER  512  //發送緩存大小 

void main()
{

	WSADATA wsaData;
	SOCKET sClient;
	int i = 0;

	//發送的數據長度
	int isndLen;

	//發送緩衝區
	char sndbuf[DATA_BUFFER];
	//發送緩存初始化
	memset(sndbuf, 0, DATA_BUFFER);
	

	const char *Serip = "192.168.43.118";//隨着程序所在主機的地址改變而改變
	int SeriPort = 5050;

	//服務器端SOCKET地址結構
	struct sockaddr_in serAddr;


	//填寫要連接的服務器地址信息
	serAddr.sin_family = AF_INET;
	serAddr.sin_port = htons(SeriPort);
	serAddr.sin_addr.s_addr = inet_addr(Serip);

	

	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		cout << "failed to load winsock" << endl;
		return;
	}


	//建立客戶端字節流式套接字(TCP套接字)
	sClient = socket(AF_INET, SOCK_STREAM, 0);
	if (sClient == INVALID_SOCKET)
	{
		cout << "socket() failed :" << WSAGetLastError() << endl;
		return;
	}

	//請求與服務器建立連接
	// cout<<"set link";
	if (connect(sClient, (struct sockaddr *)&serAddr, sizeof(serAddr)) == INVALID_SOCKET)
	{
		cout << "connect() failed: " << WSAGetLastError() << endl;
		return;
	}
	else
	{//向服務器端發送數據
		while (1)
		{
			cout << endl;
			i++;
			cout << "第" << i << "發送" << endl;

			cin >> sndbuf;

			isndLen = send(sClient, sndbuf, sizeof(sndbuf), 0);
			if (isndLen == 0)
				return;
			else if (isndLen == SOCKET_ERROR)
			{
				cout << "send() failed:" << WSAGetLastError() << endl;
				return;
			}
			cout << "-----客戶端發送內容爲----" << sndbuf << endl;
			if (strcmp(sndbuf, "quit") == 0)
			{
				int serlen = sizeof(serAddr);

				cout << "in" << endl;
				int ret;
				//char recvData[BUF_MAXLEN];
				char file_name[MAX_NAME]="姚靜.avi";
				char recv_buf[data_buffer1];

				//接收文件名
				//ret = recvfrom(sClient, file_name, MAX_NAME, 0, (sockaddr *)&serAddr, &serlen);
				//cout << ret << endl;
				/*file_name[ret] = '\0';
				cout << file_name << endl;*/
				//接收文件長度
				/*ret = recvfrom(sClient, file_name, MAX_NAME, 0, (sockaddr *)&serAddr, &serlen);
				cout << ret << endl;
				file_name[ret] = '\0';
				cout << file_name << endl;*/
				int length = 3838464;
				//sscanf(recv_buf, "%d", &length);
				cout << "-----------------------------RECEIVING...-----------------------------" << endl;
				//打開文件
				char *recvData = (char*)malloc(length);
				FILE * fp;
				if (!(fp = fopen(file_name, "wb")))
				{
					cout << "File " << file_name << " can't open" << endl;
					return;
				}
				memset(recvData, 0, length);

				char *dataptr = recvData;

				int file_len = 0;//接收文件
				file_len = recvfrom(sClient, dataptr, BUF_MAXLEN, 0, (sockaddr *)&serAddr, &serlen);
				//cout << dataptr << endl;
				int i = 1;
				while (i < length / BUF_MAXLEN)
				{
					if (file_len == INVALID_SOCKET || file_len == 0)
					{
						cout << "Receive Error" << endl;
						return;
					}
					dataptr += BUF_MAXLEN;
					file_len = recvfrom(sClient, dataptr, BUF_MAXLEN, 0, (sockaddr *)&serAddr, &serlen);
					//cout << dataptr << endl;
					i++;
				}
				ret = fwrite(recvData, sizeof(char), length, fp);//寫文件
				//cout << "收到文件內容" << recvData << endl;
				cout << "Receive " << file_name << " Successful!" << endl;
				//表明傳輸時間,對象
				SYSTEMTIME st;
				GetLocalTime(&st);
				cout << "Linking Time:" << st.wYear << "/" << st.wMonth << "/" << st.wDay << "  " << st.wHour << ":" << st.wMinute << endl;
				cout << "Server " << inet_ntoa(serAddr.sin_addr) << ":" << ntohs(serAddr.sin_port) << " Connection!" << endl;
				cout << "----------------------------------------------------------------------" << endl;
				cout << endl;
			}
		}

		
		

	}

	closesocket(sClient);

	WSACleanup();
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章