socket局域网黑窗口聊天

原创 2018年04月16日 02:11:30

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

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

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

一个服务端,两个客户端(其实应该是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

关于中文问题

不少朋友曾对虚拟小龙亭的中文显示提出了意见和建议,谨在此表示感谢。在jsp中,中文乱码常会让人心乱如麻。对于中文处理的常见对策,在网上经常可见的主要是下面2种:或者: String Hi="你好";b...
  • asper
  • asper
  • 2001-05-30 12:20:00
  • 611

利用java socket实现多线程局域网聊天应用

刚接触java网络编程,实现了利用socket多线程局域网聊天工具。先由客户端发送数据给服务器,然后由服务器把数据写入流中,发送到各个客户端中,主要涉及的技术是socket的应用,多线程的应用以及各个...
  • u013982769
  • u013982769
  • 2014-12-09 11:33:55
  • 801

Socket局域网聊天工具源码(Unity+C#)

  • 2017年07月23日 23:07
  • 42.5MB
  • 下载

C# socket 局域网聊天程序的一点心得

C# socket 局域网聊天程序的一点心得 (一)服务器与客户端的关系 1、服务器开启监听服务        服务器使用特定的端口不停的监听来自客户端的消息。(开启一个新线程进行监听)。 2、监听...
  • AwakeningWolf
  • AwakeningWolf
  • 2015-08-01 10:11:19
  • 1956

Java 套接字(Socket)实现的简单局域网点对点聊天工具

  • 2015年10月14日 20:54
  • 342KB
  • 下载

Linux socket跨局域网聊天和文件传输

自己写的小软件,基于linux socket的跨局域网聊天和文件传输
  • u011353822
  • u011353822
  • 2015-01-02 13:15:51
  • 1668

MFC socket 局域网聊天

  • 2011年03月21日 10:39
  • 1.2MB
  • 下载

Java网络编程,通过TCP,Socket实现多对一的局域网聊天室

java网络编程,通过TCP,Socket实现多对一的局域网聊天室 可以实现多个客户端连接服务器,服务器接收到信息就会把信息广播到所有的客户端...
  • qq_37267015
  • qq_37267015
  • 2017-01-10 10:05:59
  • 1842

Android基于TCP的局域网聊天通信

在同一局域网内,两台设备通过TCP进行通信聊天。
  • findhappy117
  • findhappy117
  • 2018-02-14 11:06:27
  • 30

socket编程实现的多人局域网聊天(udp)多线程

服务器端: /* * File Name: socket_udp_server.c * Author: eagle * mail: zhaocheng121@163.com * Cre...
  • DeltaForce_eagle
  • DeltaForce_eagle
  • 2015-10-10 09:57:56
  • 1627
收藏助手
不良信息举报
您举报文章:socket局域网黑窗口聊天
举报原因:
原因补充:

(最多只允许输入30个字)