控制台聊天的实现(UDP)

//接收端
#include <cstdio>
#include <cstdlib>
#include <WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
#define BUF_SIZE 256

void error_handling(const char* message);
//输入指定的接收端端口号
int main(int argc, char* argv[])
{
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);

	if (argc != 2) {
		printf("please enter %s <port>\n", argv[0]);
		exit(1);
	}

	SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
		error_handling("socket error!");
	else printf("socket has done\n");

	SOCKADDR_IN  addr,rec_addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(atoi(argv[1]));

	if(bind(sock,(SOCKADDR*)&addr,sizeof(addr)) == -1)
		error_handling("bind error");
	else printf("bind has done\n");

	char rec_msg[BUF_SIZE],send_msg[BUF_SIZE];
	int strlen=0,send_len=0;
	int addr_sz = sizeof(rec_addr);
	while (1) {
		strlen = recvfrom(sock, rec_msg, BUF_SIZE, 0, (SOCKADDR*)&rec_addr, &addr_sz);
		if (strlen == 0) continue;
		if (strlen == -1)
			error_handling("recvfrom error!");
		else 
		{
			printf("%s", rec_msg);
			memset(rec_msg, 0, sizeof(rec_msg));
		}
		//发送信息
		fgets(send_msg, BUF_SIZE, stdin);
		send_len = sendto(sock, send_msg, BUF_SIZE, 0, (SOCKADDR*)&rec_addr, addr_sz);
		if (send_len == -1) error_handling("sendto error!");
		memset(send_msg, 0, sizeof(send_msg));
	}

	closesocket(sock);
	WSACleanup();
	return 0;
}

void error_handling(const char* message)
{
	printf("%s\n", message);
	exit(1);
}
//发送端
#include <cstdio>
#include <cstdlib>
#include <WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
#define PORT 9999
#define BUF_SIZE 256
void error_handling(const char* message);

//输入接收端的IP和端口
int main(int argc, char* argv[])
{
	WSADATA wsadata;
	WSAStartup(MAKEWORD(2, 2), &wsadata);

	if (argc != 3) {
		printf("please enter %s <IP> <port>\n", argv[0]);
		exit(1);
	}

	SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
		error_handling("socket error!");
	else printf("socket has done\n");
	//fgetc(stdin);

	SOCKADDR_IN addr,local_addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(argv[1]);
	addr.sin_port = htons(atoi(argv[2]));

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

	if (bind(sock,(SOCKADDR*)&local_addr,sizeof(local_addr)) == -1)
		error_handling("bind error!");

	char send_msg[BUF_SIZE],rec_msg[BUF_SIZE];
	int strlen,rec_len;
	int addr_sz = sizeof(addr);
	//第一次发送给接收端
	fgets(send_msg, BUF_SIZE, stdin);
	strlen = sendto(sock, send_msg, BUF_SIZE, 0, (SOCKADDR*)&addr, addr_sz);
	if (strlen == -1) error_handling("sendto error!");
	memset(send_msg, 0, sizeof(send_msg));
	//下面操作跟接收端一样
	while (1) {
		rec_len = recvfrom(sock, rec_msg, BUF_SIZE, 0, (SOCKADDR*)&addr, &addr_sz);
		if (rec_len == 0) continue;
		if (rec_len == -1)
			error_handling("recvfrom error!");
		else
		{
			printf("%s", rec_msg);
			memset(rec_msg, 0, sizeof(rec_msg));
		}
	
		memset(send_msg, 0, sizeof(send_msg));
		fgets(send_msg, BUF_SIZE, stdin);
		strlen = sendto(sock, send_msg, BUF_SIZE, 0, (SOCKADDR*)&addr, addr_sz);
		if (strlen == -1) error_handling("sendto error!");
	}

	closesocket(sock);
	WSACleanup();
	return 0;
}

void error_handling(const char* message)
{
	printf("%s\n", message);
	exit(1);
}

注:

该程序使用单线程进行“回合制”交互,使用UDP协议进行通讯

使用方式:

首先要保证你的虚拟机里的windows主机和宿主机能相互ping通。然后

在将两个cpp文件编译后可将任意一方放置在虚拟机运行。比如可以把编译后的接收端文件放在虚拟机的windows系统里,用cmd运行(记得运行exe时要带参,否则运行一下就没了),然后在宿主机上运行编译好的发送端文件,跟前面的操作一样也是用cmd带参运行,具体参数我在上述程序里有讲解。在发送端运行显示“socket has done”后便可以在发送端输入消息,一旦发送成功,两端便开始“回合制”交互,直至一方停止输入(crtl+C)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值