0
点赞
收藏
分享

微信扫一扫

网络编程之重构echo服务器

泠之屋 2022-01-20 阅读 95

任务目标:基于TCP,实现echo服务器和客户端
任务描述:实现echo客户端,即通过命令行输入任何字符串,等回车后发送给服务器。发送的部分要包括换行符。然后等待服务器响应,回送部分的结束也以换行符为标志。当收到换行符结束receive,并打印之。
服务器端程序:收到换行符之后将收到的字符串原样返回给客户端,并包括换行符作为结束
任务要求:
不要动态分配内存;用指针操纵接收的数据,考虑buf有限的问题;考虑客户端和服务器端谁先关闭的问题;尽量形成多个函数。
服务器端

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

#define BUF_SIZE 10    //最大接收数
#define PORT 9190
void RecvMsg(SOCKET);
void SendMsg(SOCKET);
int main(int argc, char* argv[])
{
	WSADATA wasdata;
	SOCKET ServSock, ClntSock;
	char message[BUF_SIZE];			//数据缓冲区
	SOCKADDR_IN servAdr, clntAdr;
	int strlen, clntAdrSize;


	if (WSAStartup(MAKEWORD(2, 2), &wasdata))
	{
		cout << "加载动态winsock.dll失败!";
		exit(1);
	}

	ServSock = socket(AF_INET, SOCK_STREAM, 0);
	if (ServSock == INVALID_SOCKET)
	{
		cout << "创建套接字失败!";
		exit(1);
	}


	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAdr.sin_port = htons(PORT);

	if (bind(ServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
	{
		cout << "绑定套接字失败! ";
		exit(1);
	}

	if (listen(ServSock, 5) == SOCKET_ERROR)
	{
		cout << "监听套接字失败!";
		exit(1);
	}

	//cout << "ip: " << inet_ntoa(servAdr.sin_addr) << endl;
	clntAdrSize = sizeof(clntAdr);

	for (int i = 0; i < 5; i++)
	{
		ClntSock = accept(ServSock, (SOCKADDR*)&clntAdr, &clntAdrSize);
		if (ClntSock == -1)
		{
			cout << "接收失败!";
			exit(1);
		}
		else
			cout << "Connected client......" << i + 1 << endl;
		while ((strlen = recv(ClntSock, message, BUF_SIZE - 1, 0)) != 0)
			send(ClntSock, message, strlen, 0);
		closesocket(ClntSock);
		cout << "退出连接" << endl;
	}
	closesocket(ServSock);
	WSACleanup();

	return 0;
}

客户端

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define BUF_SIZE 1024
char message[BUF_SIZE];
int SendMsg(SOCKET);
void RecvMsg(SOCKET, int);

int main(int argc, char* argv[])
{
	WSADATA wsadata;
	SOCKET hSock;
	int str_len, recv_len, recv_cnt;
	SOCKADDR_IN servAdr;

	if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0)
	{
		cout << "加载winsock.dll失败!" << endl;
		exit(1);
	}

	hSock = socket(AF_INET, SOCK_STREAM, 0);
	if (hSock == INVALID_SOCKET)
	{
		cout << "创建套接字失败!" << endl;
		exit(1);
	}

	memset(&servAdr, 0, sizeof(servAdr));
	servAdr.sin_family = AF_INET;
	servAdr.sin_addr.s_addr = inet_addr("192.168.56.1");
	servAdr.sin_port = htons(9190);

	if (connect(hSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
	{
		cout << "连接失败!" << endl;
		exit(1);
	}
	else
		cout << "Connected......" << endl;

	while (1)
	{
		memset(message, 0, BUF_SIZE);
		fputs("请输入要发送的信息[Q ot quit]:", stdout);
		fgets(message, BUF_SIZE, stdin);

		if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
			break;
		str_len = SendMsg(hSock);

		RecvMsg(hSock, str_len);
		
		cout << "来自服务器端的消息是:" << message << endl;
	}
	closesocket(hSock);
	WSACleanup();

	return 0;
}

int SendMsg(SOCKET Sock)
{
	SOCKET hSock = Sock;
	int str_len;
	str_len = send(hSock, message, strlen(message), 0);		//传输的数据长度,在echo客户端内已知
	return str_len;
}

void RecvMsg(SOCKET Sock, int str_len)
{
	SOCKET hSock = Sock;
	int recv_len, recv_cnt;
	recv_len = 0;
	while (recv_len < str_len)
	{
		recv_cnt = recv(hSock, &message[recv_len], BUF_SIZE - 1, 0);
		if (recv_cnt == -1)
			cout << "接收失败!" << endl;
		recv_len += recv_cnt;
	}
	message[recv_len] = 0;
}


举报

相关推荐

0 条评论