socket局域网黑窗口聊天

只能实现同一局域网内的两台电脑的聊天

聊天内容通过一个黑窗口显示,另一个黑窗口用来发送消息

有点死板,必须要两台电脑都接上服务端才行

一个服务端,两个客户端(其实应该是4个吧,显示窗口也是一个客户端)

效果如图


食用方法:

TServer:服务端
Display_TCP:显示聊天内容的一个客户端(display.cpp的生成文件)
TClinet:用于发送消息的客户端


只能用于两台同一局域网的电脑聊天,而且两台电脑都要连接到服务端才行


/********************************************************************/
先一台电脑启动服务端TServer
然后再启动Display_TCP,根据提示先输入开启服务端的电脑的IP地址
    这里是有做防止非法操作的,但是并不严谨,所以还请输入正确
的ip地址,若输入出错则需删除当前文件夹内的ipconfig.txt文件,再
重新打开,也可以直接把文本内容改为正确的ip地址


输入正确的ip地址后,会自动启动TClient


然后再在另一台同一局域网的电脑里启动Display_TCP,步骤同上
之后就可以发消息了,消息内容不限长短


两边同时发送的话应该会有问题,虽然还没有尝试,但是推测应
该分两种情况
1、先连接进服务端的电脑的消息会先显示,然后再显示后连接的
2、显示后连接的客服端的一部分消息,然后完全显示先连接的,
再显示后连接客户端剩下的消息
/********************************************************************/

头文件WSAStartup.h

#ifndef WSASTARTUP_H
#define WSASTARTUP_H


#include<iostream>
#include<winsock.h>

#define SIZE_BUF 40

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

class Wsastart {
public:
	Wsastart() {
		WSADATA data;
		WORD v = MAKEWORD(2, 0);
		if (WSAStartup(v, &data)) {
			std::cout << "初始化失败" << std::endl;
			exit(0);
		}
	}
	~Wsastart() {
		WSACleanup();
	}
	static bool check_ip(char *ip);
};

enum SEND_NAME {	
	yes = 0,
	no
};


#endif

check.cpp

#include"WSAStartup.h"

bool Wsastart::check_ip(char *ip) {
	int count = 0;
	while (*ip != '\0') {
		if (*ip == '.') {
			count++;
		}
		else if(*ip > 57 || *ip < 48){
			return false;
		}
		ip++;
	}
	if (count != 3) {
		return false;
	}
	return true;
	
}

display.cpp

#include<iostream>
#include<fstream>
#include"WSAStartup.h"

int main() {
	Wsastart setSocket;

	bool about_cin;
	char save_ip[16] = "";
	std::ifstream set_config("./ipconfig.txt");
	if (set_config) {
		set_config.get(save_ip, 16, EOF);
		set_config.close();
	}
	else {
		std::cout << "请输入服务器的IP地址:";
		while ((about_cin = (bool)std::cin.getline(save_ip, 16)) == false || Wsastart::check_ip(save_ip) == false) {
			std::cout << "格式有误,请重新输入ip地址:";
				std::cin.clear();
			if (about_cin == false) {
				while (std::cin.get() != '\n');
			}
		}
		std::ofstream ip_config("./ipconfig.txt");
		ip_config << save_ip;
		ip_config.close();
	}


	std::system("start TClient.exe");

	SOCKET rec;
	rec = socket(AF_INET, SOCK_STREAM, 0);

	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8848);
	addr.sin_addr.S_un.S_addr = inet_addr(save_ip);


	connect(rec, (sockaddr *)&addr, sizeof(addr));

	char buf[SIZE_BUF+2] = "";
	int i;
	while (1) {
		std::ofstream chat_save("./chat_save.txt", std::ios::out|std::ios::trunc|std::ios::binary);
		while (1) {
			i = recv(rec, buf, SIZE_BUF + 1, 0);
			if ( i < (SIZE_BUF + 1)) {
				buf[i] = '\0';
				chat_save << buf;
				chat_save.close();
				break;
			}
			chat_save << buf;
		}
		std::ifstream chat_read("./chat_save.txt");
		while (1) {
			if (!chat_read.get(buf, 10, EOF)) {
				chat_read.close();
				break;
			}
			std::cout << buf;
		}
	}
	closesocket(rec);
	system("pause");
	return 0;
}

TClient.cpp

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdlib>
#include "WSAStartup.h"

int main() {
	Wsastart setSocket;

	char get_ip[16];
	std::ifstream ip_config("./ipconfig.txt");
	ip_config.get(get_ip, 16, EOF);
	ip_config.close();

	char name[24] = "";
	std::ifstream set_config("./name_config.txt");
	if (set_config) {
		set_config.get(name, 16, '\0');
		set_config.close();
	}
	else {
		std::cout << "请输入您的昵称(20字节以内):";
		while (1) {
			if (!std::cin.getline(name, 20)) {
				std::cout << "超出字符,请重新输入:";
				std::cin.clear();
				while (std::cin.get() != '\n');
				continue;
			}
			else if(strlen(name) == 0){
				continue;
			}
			break;
		}
		strcat(name, ":\n\t");
		std::ofstream name_config("./name_config.txt");
		name_config << name;
		name_config.close();
	}

	SOCKET s;
	s = socket(AF_INET, SOCK_STREAM, 0);

	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8849);
	addr.sin_addr.S_un.S_addr = inet_addr(get_ip);
	std::cout << "客户端已启动\n";
	std::cout << "昵称:" << name << '\n';

	connect(s, (sockaddr *)&addr, sizeof(addr));
	
	char buf[SIZE_BUF+2];
	bool neet_clear = false;
	int buf_size;

	while (1) {
		std::ofstream text_save("./text_save.txt");
		text_save << name;
		std::cout << "请输入要发送的消息:\n";
		while (1) {
			if ((bool)std::cin.getline(buf, SIZE_BUF+1) == neet_clear) {
				std::cin.clear();
			}
			else {
				buf_size = strlen(buf);
				buf[buf_size] = '\n';
				buf[buf_size + 1] = '\0';
				text_save << buf;
				text_save.close();
				break;
			}
			text_save << buf;
		}
		std::ifstream text_read("./text_save.txt",std::ios::in|std::ios::binary);
		while (1) {
			if ((bool)text_read.getline(buf, SIZE_BUF + 1, EOF)) {
				send(s, buf, strlen(buf) + 1, 0);
				text_read.close();
				break;
			}
			else {
				text_read.clear();
			}
			send(s, buf, SIZE_BUF + 1, 0);
		}
	}
	closesocket(s);
	system("pause");
	return 0;
}

TServer.cpp

#include <iostream>
#include <string.h>
#include "WSAStartup.h"

int main() {
	Wsastart setSocket;

	SOCKET sock_first;
	sock_first = socket(AF_INET, SOCK_STREAM, 0);

	sockaddr_in addr_first;
	addr_first.sin_family = AF_INET;
	addr_first.sin_port = htons(8848);
	addr_first.sin_addr.S_un.S_addr = INADDR_ANY;
	bind(sock_first, (sockaddr *)&addr_first, sizeof(addr_first));
	listen(sock_first, 5);

	SOCKET send_buf;
	sockaddr_in addr_send;
	int size1 = sizeof(addr_send);
	

	SOCKET sock_second;
	sock_second = socket(AF_INET, SOCK_STREAM, 0);

	sockaddr_in addr_second;
	addr_second.sin_family = AF_INET;
	addr_second.sin_port = htons(8849);
	addr_second.sin_addr.S_un.S_addr = INADDR_ANY;
	bind(sock_second, (sockaddr *)&addr_second, sizeof(addr_second));
	listen(sock_second, 5);

	SOCKET recv_buf;
	sockaddr_in addr_recv;
	int size2 = sizeof(addr_recv);
/*=================================================================*/
	SOCKET send_buf2;
	sockaddr_in addr_send2;
	int size3 = sizeof(addr_send2);

	SOCKET recv_buf2;
	sockaddr_in addr_recv2;
	int size4 = sizeof(addr_recv2);
/*=================================================================*/
	send_buf = accept(sock_first, (sockaddr*)&addr_send, &size1);
	if (send_buf != NULL) {
		std::cout << inet_ntoa(addr_send.sin_addr) << "连接成功\n";
	}

	recv_buf = accept(sock_second, (sockaddr*)&addr_recv, &size2);
	if (recv_buf != NULL) {
		std::cout << inet_ntoa(addr_recv.sin_addr) << "连接成功\n";
	}
/*=================================================================*/
	send_buf2 = accept(sock_first, (sockaddr*)&addr_send2, &size3);
	if (send_buf2 != NULL) {
		std::cout << inet_ntoa(addr_send2.sin_addr) << "连接成功\n";
	}

	recv_buf2 = accept(sock_second, (sockaddr*)&addr_recv2, &size4);
	if (recv_buf2 != NULL) {
		std::cout << inet_ntoa(addr_recv2.sin_addr) << "连接成功\n";
	}
/*=================================================================*/

	unsigned long ul = 1;
	ioctlsocket(recv_buf, FIONBIO, &ul);
	ioctlsocket(recv_buf2, FIONBIO, &ul);
//	ioctlsocket(send_buf, FIONBIO, &ul);
//	ioctlsocket(send_buf2, FIONBIO, &ul);
	char buf[SIZE_BUF + 1]="";
	int i = 0;
	while (1) {
		while (1) {
			i = recv(recv_buf, buf, SIZE_BUF + 1, 0);
			if (i > 0)
				break;
			i = recv(recv_buf2, buf, SIZE_BUF + 1, 0);
			if (i > 0)
				break;
		}
		send(send_buf, buf, strlen(buf)+1, 0);
		send(send_buf2, buf, strlen(buf) + 1, 0);
		memset(buf, 0, SIZE_BUF + 1);
	}
	closesocket(sock_first);
	closesocket(sock_second);

	system("pause");
	return 0;
}

源代码及debug程序下载:https://pan.baidu.com/s/1D-SR9l523WbtGkwdcBtfQw

阅读更多
文章标签: socket c 局域网聊天
上一篇头文件、声明、定义以及条件编译为什么不能定义变量的个人理解
下一篇QT学生信息管理
想对作者说点什么? 我来说一句

MFC socket 局域网聊天

2011年03月21日 1.2MB 下载

没有更多推荐了,返回首页

关闭
关闭