请对socket编程有丰富经验的朋友进来看一个boost.asio通信的问题 955错误

经验 同时被 2 个专栏收录
7 篇文章 0 订阅
6 篇文章 0 订阅

论坛首页 精选版块 论坛牛人 排行榜 论坛地图 我要发贴

论坛帮助

CSDN论坛 > C/C++ > C++ 语言

请对socket编程有丰富经验的朋友进来看一个boost.asio通信的问题 [问题点数:40分,结帖人facat]

facat

Bbs2

结帖率 97.26%

0 2011-08-11 15:35:50 回复次数9

引用 ・ 举报 ・ 楼主

我用boost.asio库写了一个server和一个client。功能很简单,client把输入的字符发送出去,server就接收下来显示出来。我现在遇到一个很奇怪的问题,就是偶尔在server端会出现995错误。995错误的意思是
“由于线程退出或应用程序请求,已中止i/o操作”

由于是偶尔出现,所以我很难差到原因。而且是一连接收几十次不出错,然后下一次就突然出错。或者接连几次出错,然后又几十次不出错。

请大家帮我看看是不是有什么地方应该处理的我没处理。

附代码在下面,不过我估计不会有人看的,只希望大家根据自己的经验提出一些可能出现995错误的原因。

公用类:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#ifndef __TCP_ECHO_CONNECTION

#define __TCP_ECHO_CONNECTION

 

#include <boost/asio.hpp>

 

class tcp_echo_connection

{

public:

    tcp_echo_connection(boost::asio::io_service& _io_srvice);

 

    //tcp_echo_connection(){};

    boost::asio::ip::tcp::socket& getsocket();

    tcp_echo_connection* getthis()

    {

        return this;

    }

private:

    boost::asio::ip::tcp::socket _socket;

};

 

tcp_echo_connection::tcp_echo_connection(boost::asio::io_service& _io_srvice) :

        _socket(_io_srvice)

{

 

}

 

boost::asio::ip::tcp::socket& tcp_echo_connection::getsocket()

{

    return _socket;

}

 

 

#endif




server:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

#define _WIN32_WINNT  0x0600

#define _GLIBCXX_DEBUG

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

 

#include <iostream>

#include <string>

#include <boost/asio.hpp>

#include <list>

#include <boost/shared_ptr.hpp>

#include <boost/shared_array.hpp>

#include <boost/bind.hpp>

#include "tcp_echo_connection.h"

using namespace std;

class tcp_echo_connection;

class tcp_echo_server;

 

class tcp_echo_server

{

public:

    tcp_echo_server(boost::asio::io_service& _io_srvice,

            boost::asio::ip::tcp::endpoint &_endpoint);

private:

    void start_acceptor(boost::asio::io_service& _io_srvice);

    void action(boost::shared_ptr<tcp_echo_connection> tcp_conn,

            const boost::system::error_code& error);

    void asy_read();

    void asy_read_handle(boost::shared_array<char> revdata,

            const boost::system::error_code& error, // Result of operation.

            std::size_t bytes_transferred // Number of bytes read.

            );

private:

    boost::asio::ip::tcp::acceptor _acceptor;

    const static int MAX_ACCEPTOR = 5;

    static int acceptor_count;

 

};

 

int tcp_echo_server::acceptor_count = 0;

 

void tcp_echo_server::start_acceptor(boost::asio::io_service& _io_srvice)

{

    acceptor_count++;

    boost::shared_ptr<tcp_echo_connection> ptr(

            new tcp_echo_connection(_io_srvice));

    cout << "start accepting" << endl;

    cout << "current accepting count: " << acceptor_count << endl;

    _acceptor.async_accept(

            ptr->getsocket(),

            boost::bind(&tcp_echo_server::action, this, ptr,

                    boost::asio::placeholders::error));

 

}

 

tcp_echo_server::tcp_echo_server(boost::asio::io_service& _io_srvice,

        boost::asio::ip::tcp::endpoint &_endpoint) :

        _acceptor(_io_srvice, _endpoint)

{

 

    start_acceptor(_io_srvice);

}

 

void tcp_echo_server::action(boost::shared_ptr<tcp_echo_connection> tcp_conn,

        const boost::system::error_code& error)

{

 

    try

    {

        if (!error)

        {

            boost::asio::ip::tcp::socket& t_socket = tcp_conn->getsocket();

            boost::shared_array<char> revdata(new char[128]);

            cout << "starting receiving" << endl;

            t_socket.async_read_some(

                    boost::asio::mutable_buffers_1(revdata.get(), 128),

                    boost::bind(&tcp_echo_server::asy_read_handle, this,

                            revdata, boost::asio::placeholders::error,

                            boost::asio::placeholders::bytes_transferred));

        }

        else

        {

            throw boost::system::error_code(error);

        }

    catch (std::exception &e)

    {

        std::cerr << e.what() << std::endl;

        acceptor_count--;

    catch (boost::system::error_code& e)

    {

        cout << "exception catch" << endl;

        cout << e.message() << endl;

        acceptor_count--;

    }

 

    for (int i = 0; i < MAX_ACCEPTOR - acceptor_count; i++)

    {

        std::cout << "start another" << std::endl;

        this->start_acceptor(_acceptor.get_io_service());

    }

 

}

 

void tcp_echo_server::asy_read_handle(boost::shared_array<char> revdata,

        const boost::system::error_code& error, // Result of operation.

        std::size_t bytes_transferred // Number of bytes read.

        )

{

    try

    {

        if (error)

        {

            cout << "error:" << error << endl;

            throw boost::system::error_code(error);

        }

        else

        {

            cout << "str is" << endl;

            cout << revdata.get() << endl;

            acceptor_count--;

            for (int i = 0; i < MAX_ACCEPTOR - acceptor_count; i++)

            {

                std::cout << "start another" << std::endl;

                this->start_acceptor(_acceptor.get_io_service());

            }

            //std::cout << "start another" << std::endl;

            //this->start_acceptor(_acceptor.get_io_service());

 

        }

 

    catch (std::exception &e)

    {

        cout << "exception catch" << endl;

        cout << e.what() << endl;

        acceptor_count--;

    catch (boost::system::error_code& e)

    {

        cout << "exception catch" << endl;

        cout << e.message() << endl;

        acceptor_count--;

    }

 

}

int main()

{

    try

    {

        boost::asio::io_service io_service;

        boost::asio::ip::tcp::resolver _resolver(io_service);

        boost::asio::ip::tcp::resolver::query _query("localhost""13");

        boost::asio::ip::tcp::resolver::iterator ite(_resolver.resolve(_query));

 

        boost::asio::ip::tcp::endpoint _endpoint(*ite);

        std::cout << _endpoint << std::endl;

        tcp_echo_server myserver(io_service, _endpoint);

        io_service.run();

    catch (std::exception& e)

    {

        std::cerr << e.what() << std::endl;

    }

 

    return 0;

}



client:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

#define _WIN32_WINNT  0x0600

 

#include <tcp_echo_connection.h>

#include <boost/asio.hpp>

#include <boost/shared_ptr.hpp>

#include <boost/bind.hpp>

#include <string>

using namespace std;

using namespace boost::asio::ip;

using namespace boost::asio;

using namespace boost;

class tcp_echo_client;

class tcp_echo_client

{

public:

    explicit tcp_echo_client(io_service& _ioservice);

private:

 

    io_service& m_io_service;

    void start_asyconnection();

    void start_syconnection();

    void action(shared_ptr<tcp_echo_connection> tcp_con,

            const boost::system::error_code &_err);

    void asy_write_handle(const boost::system::error_code& error, // Result of operation.

            std::size_t bytes_transferred // Number of bytes written.

            );

 

};

 

tcp_echo_client::tcp_echo_client(io_service &_ioservice) :

        m_io_service(_ioservice)

{

    while (1)

        start_syconnection();

 

}

 

void tcp_echo_client::start_asyconnection()

{

    shared_ptr<tcp_echo_connection> tcp_con(

            new tcp_echo_connection(m_io_service)); //,tcp::endpoint(tcp::v4(),13));

    tcp::socket& t_socket = tcp_con->getsocket();

 

    tcp::resolver _resolver(m_io_service);

    tcp::resolver::query _query("localhost""13");

    tcp::resolver::iterator ite(_resolver.resolve(_query));

 

    t_socket.async_connect(

            *ite,

            boost::bind(&tcp_echo_client::action, this, tcp_con,

                    boost::asio::placeholders::error));

 

}

 

void tcp_echo_client::start_syconnection()

{

    shared_ptr<tcp_echo_connection> tcp_con(

            new tcp_echo_connection(m_io_service)); //,tcp::endpoint(tcp::v4(),13));

    tcp::socket& t_socket = tcp_con->getsocket();

 

    tcp::resolver _resolver(m_io_service);

    tcp::resolver::query _query("localhost""13");

    tcp::resolver::iterator ite(_resolver.resolve(_query));

    string datastr;

    cout << "input something" << endl;

    getline(cin, datastr, '\n');

 

    t_socket.connect(*ite);

    boost::system::error_code _err;

    try

    {

        cout << "send : " << datastr.c_str() << endl;

        t_socket.write_some(

                boost::asio::buffer(datastr.c_str(), datastr.size() + 1), _err);

        if (_err)

        {

            throw boost::system::error_code(_err);

        }

 

    catch (std::exception &e)

    {

        cerr << e.what() << endl;

    catch (boost::system::error_code &e)

    {

        cerr << e.message() << endl;

    }

 

}

 

void tcp_echo_client::action(shared_ptr<tcp_echo_connection> tcp_con,

        const boost::system::error_code &_err)

{

    tcp::socket& t_socket = tcp_con->getsocket();

    cout << "input something" << endl;

    string inputstr("jh");

    cout << "take action" << endl;

    try

    {

 

        if (!_err)

        {

            size_t writedata;

            t_socket.async_write_some(

                    asio::buffer(inputstr.c_str(), inputstr.size()),

                    boost::bind(&tcp_echo_client::asy_write_handle, this,

                            boost::asio::placeholders::error,

                            boost::asio::placeholders::bytes_transferred));

            cout << "write " << writedata << endl;

        }

        else

        {

            throw boost::system::system_error(_err);

            //throw _err;

        }

    catch (boost::system::error_code &e)

    {

        cerr << e.message() << endl;

    }

    start_asyconnection();

 

}

 

void tcp_echo_client::asy_write_handle(const boost::system::error_code& error, // Result of operation.

        std::size_t bytes_transferred // Number of bytes written.

        )

{

 

}

 

int main()

{

    boost::asio::io_service myioservice;

    try

    {

 

        tcp_echo_client a(myioservice);

        myioservice.run();

        while (1)

            ;

    catch (std::exception &e)

    {

        cout << e.what() << endl;

    catch (boost::system::error_code &e)

    {

        cerr << e.message() << endl;

    }

 

    return 0;

}

 

问题点数:40分

CSDN推荐

CSDN今日推荐

jjajun

Bbs2

0 2011-08-11 19:01:34

引用 ・ 举报 ・ #1 得分:10

  是不是几次连续发送的间隔太短了。试着几次发送之间,停顿一下

 

facat

Bbs2

0 2011-08-11 19:29:51

引用 ・ 举报 ・ #2 得分:0

引用 1 楼 jjajun 的回复:

  是不是几次连续发送的间隔太短了。试着几次发送之间,停顿一下


我一秒钟发送一次也是一样的。

heqinlong

Bbs1

0 2011-08-11 23:32:14

引用 ・ 举报 ・ #3 得分:10

看了你的程序,我也是菜鸟,我有几个疑问

你的服务器是异步的,acceptor之后的回调函数,你用了一个异步读,但是回调函数你又建立一个acceptor,没必要吧!程序用一个acceptor,然后每次建立一个socket即可!

liugang_12026168

Bbs1

0 2011-08-12 09:54:51

引用 ・ 举报 ・ #4 得分:10

我看了你的程序,先自我总结一下。我要向你学习,你写的很规整。
1、你先这样调试一下,你在客户端发送完数据。sleep一下。最好发送字节数相同,方便调试
2、最有可能的就是接收的服务端的接收字节的原因。我之前也遇到这个原因


如果有什么不懂的可以加入这个群150712146进行交流

tan625747

Bbs4

0 2011-08-12 10:49:56

引用 ・ 举报 ・ #5 得分:10

在收到消息的地方,打印,那部断了

 

facat

Bbs2

0 2011-08-12 11:48:54

引用 ・ 举报 ・ #6 得分:0

引用 3 楼 heqinlong 的回复:

看了你的程序,我也是菜鸟,我有几个疑问

你的服务器是异步的,acceptor之后的回调函数,你用了一个异步读,但是回调函数你又建立一个acceptor,没必要吧!程序用一个acceptor,然后每次建立一个socket即可!


如果如果只建立一个socket的话,每次就只能有一个client给server发送数据。为了保证可以同时有多个client连接到server上就要多开几个acceptor。我的程序中是保持有5个acceptor开着。

facat

Bbs2

0 2011-08-13 14:01:15

引用 ・ 举报 ・ #7 得分:0

解决了,原来是shared_ptr<tcp_echo_connection>变量析构太早的原因。
让变量在asy_read_handle()执行完后析构就行了。

facat

Bbs2

0 2011-08-13 14:02:17

引用 ・ 举报 ・ #8 得分:0

引用 4 楼 liugang_12026168 的回复:

我看了你的程序,先自我总结一下。我要向你学习,你写的很规整。
1、你先这样调试一下,你在客户端发送完数据。sleep一下。最好发送字节数相同,方便调试
2、最有可能的就是接收的服务端的接收字节的原因。我之前也遇到这个原因


如果有什么不懂的可以加入这个群150712146进行交流



写的规整到说不上,因为eclipse可以帮我自动排版的。

massifking

Bbs1

0 2012-03-28 17:28:47

引用 ・ 举报 ・ #9 得分:0

我也碰到过此问题,后来发现是变量生存周期结束导致的.

  •  

本帖子已过去太久远了,不再提供回复功能。

其他相关推荐

25岁社招进阿里,从电商到有赞新零售,他仅1年就打开了马云一直想做的新领域!

最近关于「新零售」的声音此起彼伏:阿里巨资收购高鑫零售,腾讯确认入股永辉超市…… 自2016年10月马云第一次提出了「新零售」概念之后,各巨头跑马圈地,线下成为了必争之地,新零售的蓝海才刚刚打开。 而李星,曾是阿里五年的「资深软件开发工程师」。现带领着有赞零售团队,探索在未知且市场极其广大的新零售,利用人工智能、大数据等技术,为数百万商家提供完整的全渠道解决方案,昌宁号、Brookstone、贝因

SAS考试经验,考sas的朋友来看看

SAS考试经验,考sas的朋友来看看吧,对考试有帮助

百度面试(进程通信、socket)

1.  进程间通信         进程间通信主要包括管道, 系统IPC(包括消息队列,信号量,共享存储), SOCKET.   系统IPC的三种方式类同,都是使用了内核里的标识符来识别. 匿名管道( pipe ):匿名管道是一种半双工的通信方式,通常是在父子进程间使用。 命名管道 (named pipe) :命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信

为啥90后都买了房,是因为这种新套路 电白民道投资 · 燨燚

对Socket通信、TCP/IP和Http的理解

网络重下往上可分为,物理层丶数据链路层丶网络层丶传输层丶会话层丶变现层和应用层。 IP协议对应于网络层,TCP协议对应于传输层,Hrttp协议对应于应用层。他们之间的关系,传输层TCP协议是基于网络层的IP协议,而应用层的HTTP协议是基于TCP协议的,Socket本身就不是一个协议,他只是一个接口。 http是基于tcp的超文本传输协议, http与socket之间的区别 TCP/I

TCP的socket编程中常见问题及注意事项

TCP的socket编程中常见问题及注意事项

socket编程之实现一个简单的TCP通信

一、理解socket1、socket即为套接字,在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一的标识网络通讯中的一个进程,“IP地址+TCP或UDP端口号”就为socket。 2、在TCP协议中,建立连接的两个进程(客户端和服务器)各自有一个socket来标识,则这两个socket组成的socket pair就唯一标识一个连接。 3、socket本身就有“插座”的意思,因此用来形容

【小米校招笔试】假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。

2016年小米校招笔试第三题(西安站) 3 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。 假如:n = 5,m = 3,r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个

socket编程经验介绍

本文介绍了一些socket编程的经验。让大家对socket编程有更进一步的了解。

一个退役操盘手肺腑之言,写给无数正在亏钱的散户 唯木家金融 · 燨燚

基于面向连接和无连接的socket编程

基于面向连接的socket编程 基于面向连接的socket编程就是基于TCP的socket编程。基于TCP的socket编程的服务器器端程序和客户端程序的流程如下: 服务器端程序 1、创建套接字(socket); 2、将套接字绑定到一个本地地址和端口上(bind); 3、将套接字设为监听模式,准备接受客户请求(listen); 4、等待客户请求到来;当请求到来后,接受连接请

几种常用的进程间通信的方式,通信特点和通信方式的优缺点

http://blog.csdn.net/liuzhanchen1987/article/details/7452910 程序员必须让拥有依赖关系的进程集协调,这样才能达到进程的共同目标。可以使用两种技术来达到协调。第一种技术在具有通信依赖关系的两个进程间传递信息。这种技术称做进程间通信(interprocess communication)。第二种技术是同步,当进程间相互具有合作依赖时使用

扫码联系客服

扫码联系客服

官方公众号

官方公众号

关于我们招聘广告服务网站地图

QQ客服kefu@csdn.net客服论坛工作时间 8:00-22:00400-660-0108工作时间8:00-19:00

百度提供站内搜索 京ICP证09002463号

©2018 北京创新乐知信息技术有限公司版权所有

经营性网站备案信息 网络110报警服务 中国互联网举报中心 北京互联网违法和不良信息举报中心

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值