Welcome

首页 / 软件开发 / C++ / 基于流模式长连接的简单实现

基于流模式长连接的简单实现2011-06-02 csdn博客 基于流模式的长连接我们可以做很多事情,比方说在局域网内,我们建立这种模式,可以时时传输数据,而不用每次传输数据是创建socket,传输完后,关闭socket。可以减少创建销毁socket的时间。

基于流模式的下,数据一直在发送,我们需要知道,每次发送数据量,所以常见的方式时,我们在发送数据时,指定此次发送数据的长度,服务器读取流数据时,先读取数据长度,然后再按长度读取此次发送的数据。

我使用select复用IO机制实现了一个简单的client,server机制,希望对初学者有帮助

客户端代码:

1./*2. * ==================================================================3. *4. * Filename:client.cc5. *Description:6. *Version:1.07. *Created:2008年12月18日 09时50分36秒 CST8. * Revision:none *9. * Author:ugg (ugg_xchj@yahoo.com.cn)10. *Company:11. *12. * ==================================================================13. */14.15.#include <string>16.#include <iostream>17.#include <netdb.h>18.#include <sys/socket.h>19.#include <sys/types.h>20.#include <netinet/in.h>21.#include <arpa/inet.h>22.23.using namespace::std;24.25.// 默认内容设置26.string hostname="localhost";27.inthostport=7763;28.string sendContents="this is client";29.30.void getCMD(int argc, char *argv[])31.{32.switch(argc)33.{34.case 2:35.hostname = argv[1];36. break;37.case 3:38.hostname = argv[1];39.hostport = atoi(argv[2]);40.if(hostport < 1024 || hostport >65535)41.{42.cerr << "Error: port=" << hostport43.<< " Error, range 1024 - 65535" << endl;44.exit(0);45.}46.break;47.case 4:48.hostname = argv[1];49.hostport = atoi(argv[2]);50.if(hostport < 1024 || hostport >65535)51.{52.cerr << "Error: port=" << hostport53.<< " Error, range 1024 - 65535" << endl;54.exit(0);55.}56.sendContents = argv[3];57.break;58.default:59.break;60.}61.}62.63.int64.main ( int argc, char *argv[] )65.{66.getCMD(argc,argv);67.68.int fd;69.// create socket70.if((fd=socket(PF_INET,SOCK_STREAM,0)) == -1)71.{72.cerr << "Error: socket()" <<endl;73.exit(0);74.}75.//76.struct hostent *he;77.he = gethostbyname(hostname.c_str());78.if(he == NULL ) {79.cerr <<"Error: gethostbyname() error,hostname=" << hostname << endl;80.exit(0);81.}82.83.struct sockaddr_in serv_addr;84.85.serv_addr.sin_family=AF_INET;86.serv_addr.sin_port=htons(hostport);87.serv_addr.sin_addr=*((struct in_addr*)he->h_addr);88.bzero( &(serv_addr.sin_zero),8);89.90.// connction91.if(connect(fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1) {92.cerr<<"Error: connect() error"<<endl;93.exit(0);94.}95.96.cout << "send contents to server(" << hostname97.<< ":" << hostport << ")" << endl;98.cout << sendContents << endl;99.cout << "................" << endl;100.101.// 增加此次发送消息的长度102.char buffer[1024];103.sprintf(buffer,"%8d",sendContents.length());104.105.sendContents = string(buffer,8)+sendContents;106.107.const char* content = sendContents.c_str();108.int send=0;109.int length = sendContents.length();110.111.// send112.while(1)113.{114.int ret = write(fd,content+send,length-send);115.if(ret == 0)116.{117.// server close118.cerr << "Error: server close" << endl;119.exit(0);120.}121.send += ret;122.if(length == send)123.break;124.}125.126.string contents;127.// 先接受8字节,获取服务返回长度128.int ret = recv(fd,buffer,8,0);129.// 服务器关闭130.if(ret == 0)131.{132.cerr << "Error: server close" << endl;133.exit(0);134.}135.if(ret == 8)136.{137.buffer[8]="";138.int len = atoi(buffer);139.if(len < 1024){140.int rets=0;141.while((ret = recv(fd,buffer,len-rets,0))>0)142.{143.contents.append(buffer,ret);144.rets += ret;145.if(len==rets)146.break;147.}148.}else{149.int buflen=1024;150.while( (ret = recv(fd,buffer,buflen,0)) > 0)151.{152.contents.append(buffer,ret);153.len-=ret;154.if(len<2048){155.buflen=len;156.}157.if(len <= 0)158.break;159.}160.}161.}else {162.cerr << "Error: recv data Error " << endl;163.}164.165.cout << "recv: ";166.cout << contents << endl;167.168.return 0;169.} /* ----------end of function main---------- */