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

来源:互联网 发布:数据分析报告 编辑:程序博客网 时间:2024/05/22 10:34
基于流模式的长连接我们可以做很多事情,比方说在局域网内,我们建立这种模式,可以时时传输数据,而不用每次传输数据是创建socket,传输完后,关闭socket。可以减少创建销毁socket的时间。
 
基于流模式的下,数据一直在发送,我们需要知道,每次发送数据量,所以常见的方式时,我们在发送数据时,指定此次发送数据的长度,服务器读取流数据时,先读取数据长度,然后再按长度读取此次发送的数据。
 
我使用select复用IO机制实现了一个简单的client,server机制,希望对初学者有帮助
 
客户端代码:
 1./*
2. * ==================================================================
3. *
4. *       Filename:  client.cc
5. *    Description:
6. *        Version:  1.0
7. *        Created:  2008年12月18日 09时50分36秒 CST
8. *       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.int    hostport=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=" << hostport
43.                    << " 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=" << hostport
53.                    << " Error, range 1024 - 65535" << endl;
54.                exit(0);
55.            }
56.            sendContents = argv[3];
57.            break;
58.        default:
59.            break;
60.    }
61.}
62.
63.int
64.main ( int argc, char *argv[] )
65.{
66.    getCMD(argc,argv);
67.
68.    int fd;
69.    // create socket
70.    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.    // connction
91.    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(" << hostname
97.        << ":" << 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.    // send
112.    while(1)
113.    {
114.        int ret = write(fd,content+send,length-send);
115.        if(ret == 0)
116.        {
117.            // server close
118.            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]='\0';
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  ---------- */
本文来自编程入门网:http://www.bianceng.cn/Programming/cplus/201106/26898.htm