socket to realize simple chat room

socket to realize simple chat room

TCP protocol (cs architecture) on windows operating system

server Client
1. Request protocol version 1. Request protocol version
2. Create a socket 2. Create a socket
3. Create protocol address family, ip address, network port, communication protocol 3. Get the server protocol address family
4. Binding
5. Monitor
6. Wait for the client to connect 4. Connect to the server
7. Communication 5. Communication
8. Close the socket 6. Close the socket
9. Cleanup agreement 7. Cleanup agreement

Multi-client communication:

  1. The server wants to receive connections from multiple clients
  2. Multithreading to solve multi-client communication problems
    1. A client connects to the server and starts a thread to communicate with this client
    2. In the thread:
      1. Receive data from client
      2. Broadcast data to all clients currently connected to the server

Server:

// 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;
}

Client:

//#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;
}

Published 13 original articles · praised 5 · visits 459

Guess you like

Origin blog.csdn.net/why18767183086/article/details/104229120