`

Linux下基于TCP多线程服务与客户的实现

阅读更多
本例子是本人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

    Linux系统下基于Tcp的多线程大文件上传实现.pdf 本文介绍了一种基于Tcp的多线程大文件上传实现方法,在Linux系统下实现大文件上传的解决方案。该方法通过将大文件分块,并使用多线程技术来实现文件传输,提高了文件...

    Linux下基于socket多线程并发通信的实现

    总结来说,Linux下的多线程并发通信基于socket实现,结合TCP/IP协议,能够高效地处理多个客户端的并发请求。开发者需要理解套接字的概念、类型以及编程原理,同时掌握多线程编程技巧,包括线程安全、线程池等,以...

    多线程实现基于TCP的Socket通信.rar

    本项目“多线程实现基于TCP的Socket通信”聚焦于在Windows环境下,如何利用C++编程语言通过多线程技术来实现高效、稳定的网络连接。下面将详细阐述涉及的知识点。 1. **TCP协议**:TCP是一种面向连接的、可靠的、...

    基于Linux的TCP多线程网络聊天室源码(内含Makefile)

    在本项目中,我们探索的是一个基于Linux操作系统利用C语言实现的TCP多线程网络聊天室。这个项目的核心目标是让学习者深入了解TCP协议以及如何在Linux环境下利用多线程技术构建一个网络通信应用。下面将详细介绍其中...

    基于Linux的TCP多人聊天室

    C语言编写,采用CS模型,TCP、UDP网络协议实现的内网多人聊天室。 服务器:采用多线程以及线程锁处理客户端的所有请求以及信息转发任务。服务端实时显示客户的登录与登出信息;保存客户上传的共享文件(网盘功能);...

    基于linux的TCP网络聊天室设计与实现

    【基于Linux的TCP网络聊天室设计与实现】是一个项目,旨在构建一个能在多个客户端之间进行实时通信的系统,尤其强调私聊和群聊功能。在Linux操作系统环境下,TCP(传输控制协议)因其可靠性和面向连接的特性,成为...

    linux下基于TCP聊天代码

    在Linux环境下,基于TCP协议开发聊天程序是一项常见的任务,它涉及到网络编程、多线程、套接字编程等核心概念。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,是互联网协议栈中的重要...

    linux下基于TCP的多用户聊天室含文档.z

    在Linux环境下,构建一个基于TCP协议的多用户聊天室是一个典型的网络编程项目,它涉及到许多核心的计算机网络和操作系统知识。TCP(传输控制协议)是一种面向连接、可靠的传输协议,确保了数据的完整性和顺序性,...

    linux下多线程网络编程TCP服务器端数据传输代码

    在提供的压缩包中,"linux下多线程网络编程TCP服务器端数据传输代码"应该包含了实现这些步骤的C语言源代码。在使用前,务必阅读readme.txt文件,了解代码的运行环境、依赖库和使用方法。 这个程序可能包含以下关键...

    TCP多线程传输源码实例

    本教程将围绕“TCP多线程传输源码实例”展开,深入探讨如何在Linux环境下实现多线程TCP通信。 首先,让我们了解TCP的基本原理。TCP通过三次握手建立连接,并在数据传输过程中使用序列号和确认机制确保数据的可靠性...

    Linux下实现基于多线程的echo程序

    Linux下基于多线程的echo程序实现涉及了几个关键的IT知识点,包括Linux操作系统下的网络编程、多线程编程、以及使用C语言进行系统级编程。以下是对这些知识点的详细介绍。 首先,我们需要了解什么是echo程序。echo...

    linux c tcp socket 多线程简易聊天室

    在Linux系统中,C语言与TCP Socket编程相结合可以创建出多线程的简易聊天室。这个项目主要涉及以下几个核心知识点: 1. **TCP Socket编程**: - TCP(Transmission Control Protocol)是一种面向连接的、可靠的...

    Linux下多线程轻量级HTTP服务器

    本项目“Linux下多线程轻量级HTTP服务器”旨在实现一个基本的HTTP服务器,能够响应客户端的HTTP请求,并返回静态文件如HTML、CSS和JavaScript等资源。 首先,我们要理解网络协议的基础。HTTP(超文本传输协议)是...

    Linux下基于socket多线程并发通信的实现 (2).pdf

    在Linux操作系统中,基于Socket实现多线程并发通信是一种常见的网络编程方式,尤其适用于构建高效、高并发的服务端应用程序。Socket接口是TCP/IP协议栈的一部分,它为应用程序提供了跨网络进行数据交换的能力,抽象...

    linux基于tcp线程的聊天室

    总的来说,"linux基于tcp线程的聊天室"项目涵盖了网络编程、多线程编程、客户端-服务器架构等多个核心IT知识领域,是学习和实践这些技能的一个理想平台。在实际开发中,还需要考虑安全性、性能优化、错误处理等方面...

    qt tcp多线程服务端

    QT TCP多线程服务端是一种基于QT框架的网络通信实现,它利用TCP协议进行数据传输,并采用多线程技术提高服务器处理并发连接的能力。QT是一个跨平台的C++图形用户界面应用程序开发框架,广泛应用于桌面、移动和嵌入式...

    Linux下基于socket多线程并发通信的实现.docx

    在Linux操作系统中,实现基于socket的多线程并发通信是...通过以上知识点的结合,我们可以实现一个在Linux下基于socket的多线程并发通信服务器,它能够有效地处理来自多个客户端的并发连接,提供高效且稳定的网络服务。

    Linux下用Socket和多线程实现简单聊天室

    在Linux操作系统中,使用Socket和多线程技术可以构建一个简单的聊天室应用。Socket是网络通信的基本接口,它允许不同的进程或计算机之间进行数据交换。而多线程则可以提高程序的并发处理能力,使聊天室能同时处理多...

    TCP一对多通信_基于MFC多线程

    我用MFC VC6编写的一个 TCP 一对多通信的程序,就是服务器端利用多线程技术(不使用Select等任何模型), 能同时接收多个客户端的消息, 其次, 服务器端还能将消息群发给所有已连接的客户端, 实现的基本思路 是将...

Global site tag (gtag.js) - Google Analytics