本例子是本人Linux下基于TCP多线程Socket编程的第二个例子,本例子是用C++实现的
服务器采用了面向对象的多线程,用到了队列与链表,信号量(操作系统中叫PV操作)
本例子中的队列与链表源代码在前面可以找到,这里就不多贴了
此系统所支持的自定义命令跟上个例子相同,就里就不多说明了
头文件Thread.h代码,里面就一个抽象类(抽象类没有自己的实例,一定要被子类所继承)
#ifndef THREAD_H_INCLUDED
#define THREAD_H_INCLUDED
class Thread
{
public:
void ThreadEnter();
protected:
virtual void Start() = 0;
virtual void Initialize(){}
};
#endif // THREAD_H_INCLUDED
Thread.cpp代码:
#include "Thread.h"
void Thread::ThreadEnter()
{
Start();
}
以下为服务器主要头文件Server.h代码:
#ifndef SERVER_H_INCLUDED
#define SERVER_H_INCLUDED
#include "Thread.h"
#include "LinkList.h"
#include "ThreadQueue.h"
#include <netinet/in.h>
#include <pthread.h>
#include <semaphore.h>
#define MSG_SIZE 1024
#define BACKLOG 10
#define PORT 8001
class Server : public Thread
{
public:
Server();
~Server();
public:
void Start();
void Initialize();
void SendMessage(Server* serer);
static void* SendMessageThread(void* param);
void ReadMessage(Server* server);
static void* ReadMessageThread(void* param);
private:
int sock_fd,new_fds[BACKLOG],new_fd;
struct sockaddr_in serv_addr,dest_addr;
pthread_mutex_t mutex;
pthread_t pth_r,pth_s;
sem_t sem_r,sem_s;
int thread_cout;
LinkList list;
ThreadQueue queue;
DataType *pData;
};
#endif // SERVER_H_INCLUDED
以下为Thread.h实现的Thread.cpp代码:
#include "Server.h"
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
using namespace std;
//------------------------------------------------------------------
Server::Server()
{
pthread_mutex_init(&mutex,NULL);
sem_init(&sem_r,0,10);
sem_init(&sem_s,0,0);
}
//------------------------------------------------------------------
void Server::Initialize()
{
sock_fd = socket(AF_INET,SOCK_STREAM,0);
if(sock_fd < 0)
{
perror("socket fail!" );
exit(-1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = ntohs(PORT);
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
if (bind(sock_fd, (struct sockaddr*) &serv_addr,
sizeof(struct sockaddr)) < 0)
{
perror("bind fail! ");
exit(-1);
}
if(listen(sock_fd,BACKLOG) < 0)
{
perror("listen fail!" );
exit(-1);
}
cout << "listenning......" << endl;
socklen_t sin_size = sizeof(dest_addr);
while(1)
{
if(thread_cout == BACKLOG - 1)
{
return;
}
new_fd = accept(sock_fd,(struct sockaddr *)&dest_addr,&sin_size);
if(new_fd < 0)
{
perror("accept fail!" );
exit(-1);
}
cout << "\nA client has connected to me "
<< inet_ntoa(dest_addr.sin_addr)
<< ":" << ntohs(dest_addr.sin_port)
<< endl;
pthread_mutex_lock(&mutex);
thread_cout++;
list.InsertNode(thread_cout,new_fd);
pthread_mutex_unlock(&mutex);
pthread_create(&pth_r,NULL,ReadMessageThread,this);
}
}
//------------------------------------------------------------------
void Server::Start()
{
pthread_create(&pth_s,NULL,SendMessageThread,this);
Initialize();
}
//------------------------------------------------------------------
void Server::ReadMessage(Server* server)
{
int fd = server->new_fd;
char buf[MSG_SIZE];
int len;
/*
pthread_mutex_lock(&mutex);
int count = thread_cout - 1;
pthread_mutex_unlock(&mutex);
*/
while(1)
{
sem_wait(&sem_r);
if ((len = read(fd, buf, MSG_SIZE)) == -1)
{
perror("read fail!");
pthread_exit(NULL);
}
else if (len == 0)
{
cout << "Current client has disconnected to me" << endl;
//cout << "close fd = " << fd << endl;
close(fd);
list.DeleteNode(fd);
pthread_exit(NULL);
}
//cout << "read fd = " << fd << endl;
buf[len] = '\0';
DataType *data = new DataType();
data->fd = fd;
strcpy(data->buff,buf);
cout << "\nRECEIVE: " << buf
<< " receive fd = " << fd << endl;
//pthread_mutex_lock(&mutex);
queue.EnterQueue(data);
//pthread_mutex_unlock(&mutex);
//delete data;
sem_post(&sem_s);
}
}
//------------------------------------------------------------------
void* Server::ReadMessageThread(void* param)
{
Server* server = (Server *)param;
server->ReadMessage(server);
return NULL;
}
//------------------------------------------------------------------
void Server::SendMessage(Server* server)
{
while(1)
{
sem_wait(&sem_s);
int list_len = list.GetLength();
int tNewfd,tReceivefd;
//pthread_mutex_lock(&mutex);
pData = queue.OutQueue();
//int queue_len = queue.Queuelength();
//pthread_mutex_unlock(&mutex);
tReceivefd = pData->fd;
//cout << "Received fd = " << tReceivefd << endl;
pthread_mutex_lock(&mutex);
for(int i = 1; i <= list_len; i++)
{
list.GetNodeData(i,tNewfd);
//cout << "New fd = " << tNewfd << endl;
//if(queue_len != 0)
//{
if(tNewfd != tReceivefd)
{
write(tNewfd,pData->buff,sizeof(pData->buff));
cout << "Send to client successful! fd = " << tNewfd << endl;;
}
//}
}
delete pData;
pthread_mutex_unlock(&mutex);
sem_post(&sem_r);
}
}
//------------------------------------------------------------------
void* Server::SendMessageThread(void* param)
{
Server* server = (Server *)param;
server->SendMessage(server);
return NULL;
}
//------------------------------------------------------------------
Server::~Server()
{
close(sock_fd);
pthread_join(pth_r,NULL);
pthread_join(pth_s,NULL);
}
//------------------------------------------------------------------
以下为主文件main.cpp代码:
#include "Server.h"
int main(void)
{
Server* server = new Server();
server->ThreadEnter();
return 0;
} <!--v:3.2-->
分享到:
相关推荐
Linux系统下基于Tcp的多线程大文件上传实现.pdf 本文介绍了一种基于Tcp的多线程大文件上传实现方法,在Linux系统下实现大文件上传的解决方案。该方法通过将大文件分块,并使用多线程技术来实现文件传输,提高了文件...
总结来说,Linux下的多线程并发通信基于socket实现,结合TCP/IP协议,能够高效地处理多个客户端的并发请求。开发者需要理解套接字的概念、类型以及编程原理,同时掌握多线程编程技巧,包括线程安全、线程池等,以...
本项目“多线程实现基于TCP的Socket通信”聚焦于在Windows环境下,如何利用C++编程语言通过多线程技术来实现高效、稳定的网络连接。下面将详细阐述涉及的知识点。 1. **TCP协议**:TCP是一种面向连接的、可靠的、...
在本项目中,我们探索的是一个基于Linux操作系统利用C语言实现的TCP多线程网络聊天室。这个项目的核心目标是让学习者深入了解TCP协议以及如何在Linux环境下利用多线程技术构建一个网络通信应用。下面将详细介绍其中...
C语言编写,采用CS模型,TCP、UDP网络协议实现的内网多人聊天室。 服务器:采用多线程以及线程锁处理客户端的所有请求以及信息转发任务。服务端实时显示客户的登录与登出信息;保存客户上传的共享文件(网盘功能);...
【基于Linux的TCP网络聊天室设计与实现】是一个项目,旨在构建一个能在多个客户端之间进行实时通信的系统,尤其强调私聊和群聊功能。在Linux操作系统环境下,TCP(传输控制协议)因其可靠性和面向连接的特性,成为...
在Linux环境下,基于TCP协议开发聊天程序是一项常见的任务,它涉及到网络编程、多线程、套接字编程等核心概念。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,是互联网协议栈中的重要...
在Linux环境下,构建一个基于TCP协议的多用户聊天室是一个典型的网络编程项目,它涉及到许多核心的计算机网络和操作系统知识。TCP(传输控制协议)是一种面向连接、可靠的传输协议,确保了数据的完整性和顺序性,...
在提供的压缩包中,"linux下多线程网络编程TCP服务器端数据传输代码"应该包含了实现这些步骤的C语言源代码。在使用前,务必阅读readme.txt文件,了解代码的运行环境、依赖库和使用方法。 这个程序可能包含以下关键...
本教程将围绕“TCP多线程传输源码实例”展开,深入探讨如何在Linux环境下实现多线程TCP通信。 首先,让我们了解TCP的基本原理。TCP通过三次握手建立连接,并在数据传输过程中使用序列号和确认机制确保数据的可靠性...
Linux下基于多线程的echo程序实现涉及了几个关键的IT知识点,包括Linux操作系统下的网络编程、多线程编程、以及使用C语言进行系统级编程。以下是对这些知识点的详细介绍。 首先,我们需要了解什么是echo程序。echo...
在Linux系统中,C语言与TCP Socket编程相结合可以创建出多线程的简易聊天室。这个项目主要涉及以下几个核心知识点: 1. **TCP Socket编程**: - TCP(Transmission Control Protocol)是一种面向连接的、可靠的...
本项目“Linux下多线程轻量级HTTP服务器”旨在实现一个基本的HTTP服务器,能够响应客户端的HTTP请求,并返回静态文件如HTML、CSS和JavaScript等资源。 首先,我们要理解网络协议的基础。HTTP(超文本传输协议)是...
在Linux操作系统中,基于Socket实现多线程并发通信是一种常见的网络编程方式,尤其适用于构建高效、高并发的服务端应用程序。Socket接口是TCP/IP协议栈的一部分,它为应用程序提供了跨网络进行数据交换的能力,抽象...
总的来说,"linux基于tcp线程的聊天室"项目涵盖了网络编程、多线程编程、客户端-服务器架构等多个核心IT知识领域,是学习和实践这些技能的一个理想平台。在实际开发中,还需要考虑安全性、性能优化、错误处理等方面...
QT TCP多线程服务端是一种基于QT框架的网络通信实现,它利用TCP协议进行数据传输,并采用多线程技术提高服务器处理并发连接的能力。QT是一个跨平台的C++图形用户界面应用程序开发框架,广泛应用于桌面、移动和嵌入式...
在Linux操作系统中,实现基于socket的多线程并发通信是...通过以上知识点的结合,我们可以实现一个在Linux下基于socket的多线程并发通信服务器,它能够有效地处理来自多个客户端的并发连接,提供高效且稳定的网络服务。
在Linux操作系统中,使用Socket和多线程技术可以构建一个简单的聊天室应用。Socket是网络通信的基本接口,它允许不同的进程或计算机之间进行数据交换。而多线程则可以提高程序的并发处理能力,使聊天室能同时处理多...
我用MFC VC6编写的一个 TCP 一对多通信的程序,就是服务器端利用多线程技术(不使用Select等任何模型), 能同时接收多个客户端的消息, 其次, 服务器端还能将消息群发给所有已连接的客户端, 实现的基本思路 是将...