tcp、多线程-c/s简单聊天功能

只能在一个ip地址上,还不会改变ip地址。
tcp通信模型
一对一模型
1.导入头文件、库文件
2.确定版本信息,确定socket版本
3.创建socket
4.初始化协议地址簇
5.绑定(服务端
6.监听
7.接受连接(服务端连接客户端
8.通讯
9.关闭socket

server端

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

#pragma warning(disable : 4996)
#include<stdio.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//tcp通信模型
//一对一模型
//1.导入头文件、库文件
//2.确定版本信息,确定socket版本
//3.创建socket
//4.初始化协议地址簇
//5.绑定(服务端
//6.监听
//7.接受连接(服务端连接客户端
//8.通讯
//9.关闭socket
void sendmessage(SOCKET clientSocket)
{
	while(1){
		char tempbuff[128] = {};
		memset(tempbuff, 0, sizeof(tempbuff));
		printf("请输入");
		scanf_s("%s", tempbuff, sizeof(tempbuff));
		if (send(clientSocket, tempbuff, strlen(tempbuff), 0) > 0)
		{
			printf("发送成功");
		}
	}
}

void recvmessage(SOCKET clientSocket)
{
	while (true)
	{

	
	char buff[128] = {};

	
		memset(buff, 0, sizeof(buff));//初始化数组
		//第一个参数代表客户端的
		//第四个参数表示收发的方式,0表示默认方式,一次收完。
		if (recv(clientSocket, buff, sizeof(buff) - 1, 0) > 0)
		{
			printf(">>:%s\n", buff);

		}
	}
}
	//临界区变量定义
	CRITICAL_SECTION g_cs;
int main()
{

	//临界区变量初始化
	InitializeCriticalSection(&g_cs);
	HANDLE hThread1, hThread2;
   //2.确定版本信息
	WSADATA wsadate;
	WSAStartup(MAKEWORD(2, 2), &wsadate);
	if (LOBYTE(wsadate.wVersion) != 2 || HIBYTE(wsadate.wVersion) != 2)
	{
		printf("请求版本失败,启动不成功\n");
		return - 1;
	}

	//3.socket的创建
	static SOCKET serversocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == serversocket)
	{
		printf("套接字创建失败。\n");
		WSACleanup();
		return -1;
	}
	//初始化地址协议簇
	SOCKADDR_IN serveraddr = {};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(9001);//把小端转变为大端;
	serveraddr.sin_addr.S_un.S_addr = inet_addr("192.168.3.12");

	//5.绑定
	int l=bind(serversocket, (sockaddr*)&serveraddr, sizeof(serveraddr));
	if (SOCKET_ERROR == l) {
		printf("绑定不成功!");
		closesocket(serversocket);
		WSACleanup();
		return -1;
	
	}
	printf("绑定成功");

	//6.监听
	//第二个参数为监听的个数,也就是等待的队列最大的长度。
	int i = listen(serversocket, 20);
		if (SOCKET_ERROR == i) {
			printf("监听不成功!");
			closesocket(serversocket);
			WSACleanup();
			return -1;
		}
		printf("监听成功!");

	//7.接受连接
		static SOCKADDR_IN clientaddr = {};
		int len = sizeof(clientaddr);
		//第一个参数
		static SOCKET clientSocket=accept(serversocket, (sockaddr*)&clientaddr,&len);//返回的是加工后的窗口句柄

	//8.通讯
		hThread1 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)sendmessage, (LPVOID)clientSocket, 0, nullptr);
		hThread2 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)recvmessage, (LPVOID)clientSocket, 0, nullptr);

		::WaitForSingleObject(hThread1, INFINITE);
		::WaitForSingleObject(hThread2, INFINITE);
		TerminateThread(hThread1, 0);
		TerminateThread(hThread2, 0);
		//9.关闭socket
		closesocket(clientSocket);
		closesocket(serversocket);
		WSACleanup();
		return 0;
	
}



tcp通信模型
一对一模型
1.导入头文件、库文件
2.确定版本信息,确定socket版本
3.创建socket
4.初始化协议地址簇
5.连接
6.通讯
7.关闭socket

client端

// client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#pragma warning(disable : 4996)
#include<stdio.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//tcp通信模型
//一对一模型
//1.导入头文件、库文件
//2.确定版本信息,确定socket版本
//3.创建socket
//4.初始化协议地址簇
//7.连接
//8.通讯
//9.关闭socket

void sendmessage(SOCKET clientsocket)
{
	while(1){
	char buff[128] = {};
	
		memset(buff, 0, sizeof(buff));
		printf("请输入:");
		scanf_s("%s", buff, sizeof(buff) - 1);

		if (send(clientsocket, buff, strlen(buff), 0) > 0)
		{
			printf("发送成功\n");
		}
	}
}

void recvmessage(SOCKET clientsocket)
{
	while (1) {

		char tempbuff[128] = {};
		memset(tempbuff, 0, sizeof(tempbuff));
		char tempBuff[128] = {};
		if (recv(clientsocket, tempBuff, sizeof(tempBuff) - 1, 0) > 0)
		{
			printf("服务器发回>> : %s\n", tempBuff);
		}
	
	}
}
//临界区变量定义
CRITICAL_SECTION g_cs;

int main()
{
	//2.确定版本信息
	WSADATA wsadate;
	HANDLE hThread1, hThread2;
	WSAStartup(MAKEWORD(2, 2), &wsadate);
	if (LOBYTE(wsadate.wVersion) != 2 || HIBYTE(wsadate.wVersion) != 2)
	{
		printf("请求版本失败,启动不成功\n");
		return -1;
	}

	//3.socket的创建
	static SOCKET clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (INVALID_SOCKET == clientsocket)
	{
		printf("套接字创建失败。\n");
		WSACleanup();
		return -1;
	}

	//4.初始化地址协议簇
	static SOCKADDR_IN serveraddr = {};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(9001);//把小端转变为大端;
	serveraddr.sin_addr.S_un.S_addr = inet_addr("192.168.3.12");
    //5.连接
	int j=connect(clientsocket, (sockaddr*)&serveraddr, sizeof(serveraddr));
	if (SOCKET_ERROR == j)
	{
		printf("连接失败");
		WSACleanup();
		return -1;
	}
	printf("连接成功");

     //6.通讯
	hThread1 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)sendmessage, (LPVOID)clientsocket, 0, nullptr);
	hThread2 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)recvmessage, (LPVOID)clientsocket, 0, nullptr);

	::WaitForSingleObject(hThread1, INFINITE);
	::WaitForSingleObject(hThread2, INFINITE);
	TerminateThread(hThread1, 0);
	TerminateThread(hThread2, 0);
	//9.关闭socket
	closesocket(clientsocket);
	WSACleanup();
	return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风赤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值