C++ 实现简单Tcp服务器端 -- 多线程方式(包含客户端)

一个简单的聊天服务器端程序,多线程设计,针对多客户端。windows平台

服务器:


#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
using namespace std;

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


//一个简单的聊天程序 针对多客户端

//stdcall 的线程处理函数
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);

int main() {

	//加载winsock2的环境
	WSADATA wd;
	if(0 != WSAStartup(MAKEWORD(2, 2), &wd)) {
		cout << "WSAStartup error : " << GetLastError() << endl;
		return 0;
	}

	//1. 创建流式套接字
	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(INVALID_SOCKET == s) {
		cout << "socket error : " << GetLastError() << endl;
		return 0;
	}

	//2. 绑定端口和Ip
	sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8891);
	inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);//ip地址转网络字节序

	int len = sizeof(sockaddr_in);
	if(SOCKET_ERROR == bind(s, (SOCKADDR*)&addr, len)) {
		cout << "bind error : " << GetLastError() << endl;
		return 0;
	}

	//3. 监听
	listen(s, 5);

	//主线程循环接收客户端的链接
	while(true) {
		sockaddr_in addrClient;
		len = sizeof(sockaddr_in);

		//4. 接收成功返回与client通讯的socket
		SOCKET c = accept(s, (SOCKADDR*)&addrClient, &len);
		if(INVALID_SOCKET != c) {
			//创建线程 并且传入与client通讯的套接字
			HANDLE hThread = CreateThread(NULL, 0, ThreadFun, (LPVOID)c, 0, NULL);
			CloseHandle(hThread); //关闭对线程的引用
		}
	}

	//6. 关闭监听套接字
	closesocket(s);
	
	//清理winsock2的环境
	WSACleanup();
	
	return 0; 
}

DWORD WINAPI ThreadFun(LPVOID lpThreadParameter) {
	//5. 与客户端通讯 发送或者接收数据
	SOCKET c = (SOCKET) lpThreadParameter;
	cout << "欢迎" << c << "进入聊天室!"<< endl;

	//发送数据
	char buf[100] = {0};
	sprintf_s(buf, "欢迎%d 进入聊天室!", c);
	send(c, buf, 100, 0);

	//循环接收客户端数据
	int ret = 0;
	do 
	{
		char buf[100] = {0};
		ret = recv(c, buf, 100, 0);
		cout << c << "  说: " << buf << endl;

	} while (ret != SOCKET_ERROR && ret != 0);

	cout << c << "离开了聊天室!" << endl;

	return 0;
}

客户端:


#include <winsock2.h>//winsock2的头文件
#include <WS2tcpip.h>
#include <iostream>
using  namespace std;

//勿忘,链接dll的lib
#pragma comment(lib, "ws2_32.lib")

int  main() {

	//加载winsock2的环境
	WSADATA  wd;
	if(WSAStartup(MAKEWORD(2, 2), &wd) != 0) {
		cout << "WSAStartup  error:" << GetLastError() << endl;
		return 0;
	}

	//1.创建流式套接字
	SOCKET  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(s == INVALID_SOCKET) {
		cout << "socket  error:" << GetLastError() << endl;
		return 0;
	}

	//2.链接服务器
	sockaddr_in   addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8891);
	inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);//ip地址转网络字节序

	int len = sizeof(sockaddr_in);
	if(connect(s, (SOCKADDR*)&addr, len) == SOCKET_ERROR) {
		cout << "connect  error:" << GetLastError() << endl;
		return 0;
	}

	//3接收服务端的消息
	char buf[100] = { 0 };
	recv(s, buf, 100, 0);
	cout << buf << endl;

	//3随时给服务端发消息
	int  ret = 0;
	do {
		char buf[100] = { 0 };
		cout << "请输入聊天内容:";
		cin >> buf;
		ret = send(s, buf, 100, 0);
	} while(ret != SOCKET_ERROR&& ret != 0);


	//4.关闭监听套接字
	closesocket(s);

	//清理winsock2的环境
	WSACleanup();



	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值