//内容描述:伺服器通過socket接收資料,他不停地監聽是否有用戶端來與其進行連接配接,如果有,就建立一個線程來處理用戶端發過來的資料,如果用戶端發送資料結束或者由于某種原因伺服器端接收資料失敗,則伺服器終止接收。
//在這裡簡單地實作一下,如果在工作當中要用到這種傳輸模型,則要比這個要考慮的嚴謹的多。如更健全的資料封裝,異常處理,資料池,發送失敗處理,接收失敗處理,資料儲存,甚至是還要加上生産者消費者模型。
//用戶端程式很簡單
// more Client.cpp
#include <iostream>
using namespace std;
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstdlib>
int main()
{
int sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd == -1)cout << "client socket create error" << endl,exit(-1);
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(22222);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sd, (struct sockaddr*)&addr, sizeof(addr));
if(res == -1)cout << "connect failed" << endl,exit(-2);
cout << "start send messages" << endl;
char buf[222] = {};
cin.getline(buf,222);
//發送資料,為了讓服務端能更容易看出多線程的效果,這裡讓同一條資訊連續發送15次,
//每次隔一秒,這樣就有可能一個人,用同一台機子,啟動多個用戶端,以便可以觀察到伺服器的動态,哎,這樣處理也是用心良苦啊~~
int i =15;
while(i--)
{
send(sd, buf, sizeof(buf), 0);
sleep(1);
}
close(sd);
return 0;
}
//伺服器端
#include <iostream>
using namespace std;
#include <cstdlib>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include "thread_base.h"
class RecvData:public ThreadBaseClass
{
public:
int csd;
char buf[222];
public:
RecvData()
{
csd = -1;
memset(buf, 0, sizeof(buf));
}
public:
void run()
{
int res;
while(1)
{
res = recv(csd, buf, sizeof(buf), 0);
if(res > 0)
cout << buf << endl;
else
{
close(csd);
break;
}
}
cout << "delete this" << endl;
delete this;//注意垃圾回收,雖然“delete this ”這種方式很不雅觀,但是它也可以達到及時回收記憶體的效果。
}
};
int main()
{
int sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd == -1)cout << "socket create error" << endl,exit(-1);
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(22222);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = bind(sd, (struct sockaddr*)&addr, sizeof(addr));
if(res == -1)cout << "bind error" << endl,exit(-2);
cout << "bind success" << endl;
if(-1 == listen(sd,10))cout << "listen error" << endl,exit(-3);
struct sockaddr_in c_addr = {};
socklen_t len = sizeof c_addr;
while(1)
{
cout << "start accept" << endl;
int csd = accept(sd, (struct sockaddr*)&c_addr, &len);
cout << "accept success" << endl;
RecvData *pRecvData = new RecvData();
pRecvData->csd = csd;
pRecvData->start();
}
return 0;
}