计算机网络实验一 完整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();
}


 

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