toma para realizar sala de chat simple

toma para realizar sala de chat simple

Protocolo TCP (arquitectura cs) en el sistema operativo Windows

El servidor Cliente
1. Solicitar versión de protocolo 1. Solicitar versión de protocolo
2. Crear un zócalo 2. Crear un zócalo
3. Crear familia de direcciones de protocolo, dirección IP, puerto de red, protocolo de comunicación 3. Obtenga la familia de direcciones del protocolo del servidor
4. Encuadernación
5. Monitor
6. Espere a que el cliente se conecte 4. Conéctese al servidor
7. comunicación 5. Comunicación
8. Cerrar el zócalo 6. Cerrar el zócalo
9. Acuerdo de limpieza 7. Acuerdo de limpieza

Comunicación multicliente:

  1. El servidor quiere recibir conexiones de múltiples clientes.
  2. Multithreading para resolver problemas de comunicación multicliente
    1. Un cliente se conecta al servidor e inicia un hilo para comunicarse con este cliente
    2. En el hilo:
      1. Recibir datos del cliente
      2. Transmitir datos a todos los clientes actualmente conectados al servidor

Servidor:

// server.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

//#include "pch.h"
#include <iostream>
#include "winsock2.h"
#include "stdlib.h"
#include "stdio.h"
#include "string"
#pragma comment (lib, "ws2_32.lib")

using namespace std;


SOCKET clientSocket[1024];
int k = 0;

void communication(LPVOID n)
{
	char buff[256];
	int r;
	int i = (int)n;
	//cout << i << ":" << endl;
	while (1)
	{

		memset(buff, 0, 256);
		r = recv(clientSocket[i - 1], buff, 255, NULL);
		if (r > 0)
		{
			cout << i << ":  " << buff << endl;
			for (int j = 0; j < k; j++)
			{
				send(clientSocket[j], buff, strlen(buff), NULL);
			}
		}

	}
}


int main()
{

	//加载socket库 版本号
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData) != 0;//成功==0
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		cout << "请求版本失败!\n" << endl;
		return -1;
	}
	cout << "请求版本成功!\n" << endl;
	//创建socket
	//sockSer = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);//AF=Address family ,ipv4,TCP,0
	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (serverSocket == INVALID_SOCKET)
	{
		cout << "创建socket失败!\n" << endl;
		return -1;
	}
	cout << "创建socket成功!\n" << endl;
	//addrSer.sin_addr.S_un.S_addr
	SOCKADDR_IN addr = { 0 };

	//初始化地址
	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");// htonl(INADDR_ANY);//inet_addr("192.168.0.13");//dec--->2进制-->网络字节序
	addr.sin_family = AF_INET;
	addr.sin_port = htons(10086);//端口号~65535
	//绑定Socket
	int r = bind(serverSocket, (SOCKADDR*)&addr, sizeof(addr));
	if (r == -1)
	{
		cout << "bind失败!\n" << endl;
		return -1;
	}
	cout << "bind成功!\n" << endl;
	//listen
	r = listen(serverSocket, 10);
	if (r == -1)
	{
		cout << "listen失败!\n" << endl;
		return -1;
	}
	cout << "listen成功!\n" << endl;
	//连接
	//地址族
	SOCKADDR_IN cAddr = { 0 };
	int len = sizeof cAddr;

	//SOCKET clientSocket[1024];
	int i = 0;
	while (i < 1024)
	{
		clientSocket[i++] = accept(serverSocket, (sockaddr*)&cAddr, &len);
		k++;
		if (clientSocket[i - 1] == SOCKET_ERROR)
		{
			cout << "错误的客户端!\n" << endl;
			closesocket(serverSocket);
			WSACleanup();
			return -1;
		}
		cout << "有客户端接入进来!" << inet_ntoa(cAddr.sin_addr) << endl;
		CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)communication, (LPVOID)i, NULL, NULL);
	}


	//closesocket(clientSocket);
	//closesocket(serverSocket);
	//WSACleanup();
	return 0;
}

Cliente:

//#include "pch.h"
#include <iostream>
#include "winsock2.h"
#include "stdlib.h"
#include "stdio.h"
#include "string"
#pragma comment (lib, "ws2_32.lib")

//#include "graphics.h"

using namespace std;

SOCKET serverSocket;//服务器


void recvAndShow()
{
	int r, i = 0;
	char buff[256];
	//ofstream out;
	while (1)
	{
		memset(buff, 0, 256);
		r = recv(serverSocket, buff, 255, NULL);
		if (r > 0)
		{
		//	out.open("QQ.txt", ios::app||ios::_Nocreate);
		//	out << buff << endl;
			//outtextxy(0, i * 20, buff);
			i++;
			//out.close();
		}
	}
}

int main()
{
	//initgraph(300, 300, SHOWCONSOLE);
	//加载socket库 版本号

	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData) != 0;//成功==0
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		cout << "请求版本失败!\n" << endl;
		return -1;
	}
	cout << "请求版本成功!\n" << endl;

	//创建socket

	serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (serverSocket == INVALID_SOCKET)
	{
		cout << "创建socket失败!\n" << endl;
		return -1;
	}
	cout << "创建socket成功!\n" << endl;

	//地址族

	SOCKADDR_IN addr = { 0 };

	//初始化地址

	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");// htonl(INADDR_ANY);//inet_addr("192.168.0.13");//dec--->2进制-->网络字节序
	addr.sin_family = AF_INET;
	addr.sin_port = htons(10086);//端口号~65535尽量大于1W

	//连接到服务器

	int r = connect(serverSocket, (SOCKADDR*)&addr, sizeof addr);
	if (r == -1)
	{
		cout << "连接服务器失败!\n" << endl;
		return -1;
	}
	cout << "连接服务器成功!\n" << endl;

	CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)recvAndShow, NULL, NULL, NULL);

	char buff[256];
	while (1)
	{
		memset(buff, 0, 256);
		cout << "你要发啥?\n" << endl;
		cin >> buff;
		r = send(serverSocket, buff, strlen(buff), NULL);
		//if (r > 0) cout << "发送" << r << "字节到服务器成功!\n" << endl;

	}
	//closesocket(serverSocket);
	//WSACleanup();
	return 0;
}

Publicado 13 artículos originales · elogiado 5 · visitas 459

Supongo que te gusta

Origin blog.csdn.net/why18767183086/article/details/104229120
Recomendado
Clasificación