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