TCP多线程服务器

TCP多线程服务器

C-S模型

c-s模型即客户-服务器模型,要实现他们之间的通信,服务器端和客户端各需要完成以下的工作:

服务器端需完成的工作

socket:建立套接字
bind:发布端口
listen:开始侦听
accept:接纳客户端连接
send/recv/recvfrom:收发数据


客户端需完成的工作
socket:建立套接字
bind:发布端口
connect:连接到服务器

send/recv/recvfrom:收发数据


三次握手通信的流程如下图



单线程服务器请参照这篇文章:http://blog.csdn.net/ccsuxwz/article/details/65937565


实现多线程服务器需要用到线程函数

每有一个新的客户端连接上,就需要为该连接开辟一个新的线程,每个客户端需要建立连接后才能与服务器端进行通信。



下面是具体实现:

/*
*multi-server.cpp
*2017年6月11日
*author:xwz
*编译器:vs2015 
*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
#include<process.h>
using namespace std;

enum{PORT = 8621};

void thread_fun(void *p)
{
	char s[1024];
	SOCKET socka = (SOCKET)p;
	char *str = "hello client!";

	sockaddr_in sa = { AF_INET };
	int n_Len = sizeof(sa);

	send(socka, str, strlen(str), 0);
	getpeername(socka, (sockaddr*)&sa, &n_Len);
	cout << inet_ntoa(sa.sin_addr) << "-" << htons(sa.sin_port) << "登录:" << endl;
	while (true)						//循环发送数据
	{
		int i = recv(socka, s, sizeof(s), 0);
		if (i <= 0)
		{
			cout << GetLastError() << endl;
			cout << inet_ntoa(sa.sin_addr) << "-" << htons(sa.sin_port) << "退出:" << endl;
			break;
		}
		s[i] = 0;
		cout << inet_ntoa(sa.sin_addr) << "-" << htons(sa.sin_port)<< "说:" << s << endl;
	}
}

int main()
{
	WSADATA wd;
	WSAStartup(0x0202, &wd);						//初始化加载ws2_32.lib  
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);	//初始化套接字
	if (sock == INVALID_SOCKET)
	{
		cout << GetLastError() << endl;
		return -1;
	}

	sockaddr_in sa = { AF_INET,htons(PORT) };
	if (bind(sock, (sockaddr*)&sa, sizeof(sa)) < 0)				//绑定端口
	{
		cout << GetLastError() << endl;
		return -1;
	}

	listen(sock, 5);											//监听

	while (true)
	{
		SOCKET socka = accept(sock,0,NULL);					//通信套接字
		_beginthread(thread_fun, 0, (void*)socka);			//创建线程 
	}
	return 0;
}

/*multi-client.cpp*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
using namespace std;

enum { PORT = 8621 };

int main()
{
	WSADATA wd;
	WSAStartup(0x0202, &wd);						//初始化加载ws2_32.lib  
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);	//初始化套接字
	if (sock == INVALID_SOCKET)
	{
		cout << GetLastError() << endl;
		return -1;
	}

	sockaddr_in sa = { AF_INET,htons(PORT) };							//指明地址信息
	sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	int n_Len = sizeof(sa);
	
	if(SOCKET_ERROR ==connect(sock, (sockaddr*)&sa, n_Len))							//连接
	{
		cout << GetLastError() << endl;
		return -1;
	}


	char s[1024];

	int n = recv(sock, s, sizeof(s), 0);					//接收数据
	if (n > 0)
	{
		s[n] = 0;
		cout << s << endl;
	}

	while (true)
	{
		cout << "请输入要发送的内容:";
		cin >> s;
		send(sock, s, strlen(s), 0);
	}
	return 0;
}



发布了64 篇原创文章 · 获赞 141 · 访问量 21万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章