欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机网络实验一 完整TCP/UDP协议 服务端客户端代码

程序员文章站 2022-06-06 16:52:04
...

实验报告

完整代码如下:

注: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();
}