`
sogo6
  • 浏览: 113394 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

基于流模式长连接的简单实现

阅读更多
服务器端代码

/*
*=====================================================================================
*
*   Filename: server.cc
*  Description: 
*    Version: 1.0
*    Created: 2008年12月18日09时50分50秒CST
*   Revision: none*
*    Author: ugg(ugg_xchj@yahoo.com.cn)
*    Company: 
*
*=====================================================================================
*/
#include<string>
#include<iostream>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<map>
usingnamespace::std;
structclientInfo
{
  stringhost;
  intport;
};
typedefmap<int,clientInfo>mapgroups;
typedefmap<int,clientInfo>::iteratormapgroupsor;
typedefmap<int,clientInfo>::const_iteratormapgroupscor;
// 记录客户端的信息
mapgroupsgroups;
//默认内容设置
stringhostname="localhost";
int  hostport=7763;
stringserversendContents="thisisserver";
voidgetCMD(intargc,char*argv[])
{
  switch(argc)
  {
    case2:
      hostname=argv[1];
     break;
    case3:
      hostname=argv[1];
      hostport=atoi(argv[2]);  
      if(hostport<1024||hostport>65535)
      {
        cerr<<"Error:port="<<hostport 
          <<"Error,range1024-65535"<<endl;
        exit(0);
      }
      break;
    case4:
      hostname=argv[1];
      hostport=atoi(argv[2]);  
      if(hostport<1024||hostport>65535)
      {
        cerr<<"Error:port="<<hostport 
          <<"Error,range1024-65535"<<endl;
        exit(0);
      }
      serversendContents=argv[3];  
      break;
    default:
      break;
  }
}  
voidclearfd(intfd,fd_set&rdfds)
{
  FD_CLR(fd,&rdfds); 
  mapgroupsorit=groups.find(fd);
  if(it!=groups.end())
  {
    cerr<<"clienthost="<<it->second.host<<",port="<<it->second.port 
      <<"close"<<endl;
    groups.erase(fd);
  }
}
//recvandsendmessage
voidrecvandsend(intfd,fd_set&rdfds,string&contents,conststring&texts)
{
  //接受消息
  charbuffer[1024];
  intrets=0;
  intret=0;
  ret=recv(fd,buffer,8,0);
  if(ret==0)
  {
    clearfd(fd,rdfds);
    return;
  }
  if(ret==8)
  {
    buffer[8]='';
    intlen=atoi(buffer);
    if(len<1024){
      while((ret=recv(fd,buffer,len,0))>0)
      {
        contents.append(buffer,ret);
        rets+=ret;
        len-=ret;
        if(len==0)
          break;
      }
      if(ret==0){
        clearfd(fd,rdfds);
        return;
      }
    }else{
      intbuflen=1024;
      while((ret=recv(fd,buffer,buflen,0))>0)
      {
        contents.append(buffer,ret);
        rets+=ret;
        len-=ret;
        if(len<2048){
          buflen=len;
        }
        if(len<=0)
          break;
      }
      if(ret==0){
        clearfd(fd,rdfds);
        return;
      }
    }
  }else{
    clearfd(fd,rdfds);
    return;
  }
  //发送信息
  sprintf(buffer,"%8d",texts.length());  
  stringsendContents=string(buffer,8);
  sendContents+=texts;
  constchar*content=sendContents.c_str();
  intsend=0;
  intlength=sendContents.length();
  //send
  while(1)
  {
    intret=write(fd,content+send,length-send);
    if(ret==0)
    {
      //serverclose
      cerr<<"Error:serverclose"<<endl;
      clearfd(fd,rdfds);
      return;
    }
    send+=ret;
    if(length==send)
      break;
  }
}  
int
main(intargc,char*argv[])
{
  getCMD(argc,argv);
  intfd; 
  //createsocket
  if((fd=socket(PF_INET,SOCK_STREAM,0))==-1)
  {
    cerr<<"Error:socket()"<<endl;
    exit(0);
  }
  // 
  structhostent*he;
  he=gethostbyname(hostname.c_str());
  if(he==NULL){
    cerr<<"Error:gethostbyname()error,hostname="<<hostname<<endl;
    exit(0);
  }
  structsockaddr_inserv_addr;
  serv_addr.sin_family=AF_INET;
  serv_addr.sin_port=htons(hostport);
  serv_addr.sin_addr=*((structin_addr*)he->h_addr);
  bzero(&(serv_addr.sin_zero),8);
  //bind
  if(bind(fd,(structsockaddr*)&serv_addr,sizeof(serv_addr))==-1){
    cerr<<"Error:bind()error"<<endl;
    exit(0);
  }
  //listen
  intret_listen=listen(fd,5);
  if(ret_listen<0)
  {
    cerr<<"Error:Listenporterror,socketfd:"<<fd<<endl;
    cerr<<"Error:listenerrno="<<ret_listen<<endl;
    exit(0);
  }
  fd_setrdfds;
  intnfds;
  //Firstpollthesockets
  FD_ZERO(&rdfds);
  FD_SET(fd,&rdfds);
  while(1)
  {
    if((nfds=select(FD_SETSIZE,&rdfds,NULL,NULL,NULL))<0){
      if(errno!=EINTR){
        cerr<<"Error:selecterror"<<endl;
        exit(3);
      }
    }
    if(FD_ISSET(fd,&rdfds))
    {
      socklen_tlen;
      structsockaddr_inclient_addr;
      len=sizeof(structsockaddr);
      intclientfd=accept(fd,(structsockaddr*)&client_addr,&len);
      if(clientfd==-1)
      {
        cerr<<"Error:acceptclienterror"<<endl;
      }else{
        clientInfoinfo;  
        info.host=inet_ntoa(client_addr.sin_addr);
        info.port=ntohs(client_addr.sin_port);
        cerr<<"server:gotconnectionfrom"<<info.host 
          <<",port"<<info.port<<endl;
        groups.insert(make_pair(clientfd,info));
        FD_SET(clientfd,&rdfds);
      }
    }else{
      mapgroupscorit;
      for(it=groups.begin();it!=groups.end();++it)
      {
        if(FD_ISSET(it->first,&rdfds))
        {
          stringstrRev;
          recvandsend(it->first,rdfds,strRev,serversendContents);     
          break;
        }
      }
    }
  }  
  return0;
}       /*---------- endoffunctionmain ----------*/

  上面的代码在linux下已经编译通过
分享到:
评论

相关推荐

    TCP长短连接简单Demo

    在这个"TCP长短连接简单Demo"中,`TCP_Connection_Server`和`TCP_Connection_Client`是主要的源代码文件。服务器端`TCP_Connection_Server`负责监听和接受客户端的连接请求,管理与多个客户端的连接,并处理接收到的...

    基于C/s模式简单聊天系统

    【标题】"基于C/S模式简单聊天系统"指的是在客户端/服务器(Client/Server, C/S)架构下设计和实现的一个简易聊天应用。C/S模式是计算机网络中常见的一种架构,其中客户端(Client)作为用户界面,负责与用户交互,...

    基于Java C/S模式的简单学生管理系统

    【基于Java C/S模式的简单学生管理系统】是一个利用Java编程语言实现的客户端/服务器(Client/Server,C/S)架构的软件应用,主要用于演示学生信息的管理。由于它并未包含管理员功能,所以其功能可能相对基础,适用...

    CSharp HTTP长连接(Comet)

    在WinForm应用中,通常会使用控件如WebBrowser或自定义的Socket实现长连接。以下是一个简单的WebBrowser控件示例: ```csharp private void Form1_Load(object sender, EventArgs e) { webBrowser1.Navigate(...

    基于TCP协议的简单即时通信软件的设计与实现

    "基于TCP协议的简单即时通信软件的设计与实现" 本文主要介绍了基于TCP协议的简单即时通信软件的设计与实现,旨在设计一个能够处理多用户进行实时、安全的即时通信系统。本系统采用C/S模式,服务器负责客户端的登录...

    java实现C/S模式聊天室

    Java实现的C/S模式聊天室是一个典型的网络编程项目,它涉及到多线程、Socket通信、IO流处理以及用户界面设计等多个重要知识点。在这个项目中,我们将深入探讨这些关键概念。 首先,C/S(Client/Server)模式是...

    基于C++, python实现TCP的socket网络传输视频

    4.流模式与数据报模式 ; 5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。 接下来将以图片传输为例,用Python和C++实现服务端和客户端。这里不用语言得到的端口之间也可以互相连接。 二. 运行...

    基于ASP.NET的工作流批核系统(.NET 3.5框架的WF技术实现)

    它支持四种主要的工作流模式:顺序流程、状态机流程、活动图和业务流程建模语言(BPMN)流程。WF的工作流实例可以通过持久化存储在数据库中,以便在需要时恢复和继续执行,这在批核系统中是非常关键的功能。 在基于...

    WorkFlow C++ 工作流图形

    4. **事件驱动编程**:工作流的执行通常基于事件,如用户交互或任务完成,因此需要理解和实现事件驱动的编程模型。 5. **状态机**:工作流的每个任务可能处于不同的状态(如等待、运行、完成等),实现一个状态机...

    基于thinkphp 5.1 + workman + gateway 实现简单的在线客服聊天系统

    在线客服聊天系统的实现涉及到多个技术栈的整合,本项目基于流行的PHP框架ThinkPHP 5.1,结合高性能的异步网络通信库Workerman以及GatewayWorker,构建了一个简单但功能完善的实时通讯平台。以下将详细解释这些关键...

    基于SSM框架实现简单的登录注册功能【数据库+源码】

    本项目旨在帮助初学者通过实践掌握基于SSM实现简单登录注册功能的基本步骤和技巧。 首先,`Spring`作为核心容器,管理着应用的bean和依赖注入(DI)。在`pom.xml`中,我们需要添加Spring的相关依赖,如`spring-...

    用着色Petri网建模工作流模式

    使用着色Petri网可以通过简单的弧连接来实现这一模式,确保活动之间的有序执行。 - **并行执行模式**:并行执行模式允许同时执行多个活动。着色Petri网通过分叉弧和合并弧来实现活动的并发执行,有效地模拟了并行...

    基于 vue、ant-design-vue 的自定义Antdv 工作流组件

    本项目“基于vue、ant-design-vue的自定义Antdv工作流组件”就是一个这样的解决方案,旨在提供一个高度可定制、功能丰富的Web工作流平台。 首先,我们要理解Vue.js,它是一个轻量级的前端框架,以其易学易用、高效...

    Java基于Swing实现的简单聊天室,支持多人在线闲谈.zip

    这个“Java基于Swing实现的简单聊天室,支持多人在线闲谈.zip”文件是一个示例项目,展示了如何利用Swing构建一个基本的多用户聊天应用。下面将详细阐述其涉及的关键知识点。 1. **Swing组件**:Swing提供了丰富的...

    基于Winsock实现聊天程序系统

    ### 基于Winsock实现聊天程序系统的相关知识点 #### 1. 绪论 - **背景**: 随着21世纪的到来,互联网技术飞速发展,深刻改变了人们的沟通方式。从简单的在线购物到复杂的远程协作,互联网已成为连接全球的重要桥梁...

    基于BS模式的superflow工作流平台v4.1-avi综合演示

    **基于BS模式的SuperFlow工作流平台v4.1综合演示** 在信息技术领域,工作流管理系统(Workflow Management System,简称WfMS)是用于自动化业务流程的重要工具。SuperFlow工作流平台是一个这样的系统,它专注于提供...

    计算机网络课程设计 基于TCP协议的文件传输简单实现

    在这个基于TCP协议的文件传输简单实现的课程设计中,我们将深入探讨如何利用TCP协议来构建一个基本的文件传输系统。 首先,TCP协议的核心特点是提供端到端的、面向连接的服务。这意味着在数据传输前,发送方和接收...

    基于TCP协议的简单即时通信软件的设计与实现(含源文件).pdf

    在基于TCP协议的即时通信软件设计中,通常采用C/S(Client/Server)架构,即客户端(Client)和服务器端(Server)的模式。服务器负责处理客户端的登录验证、存储用户的好友信息,并定期发送心跳包来保持连接状态。...

Global site tag (gtag.js) - Google Analytics