1. 程式人生 > >請對socket程式設計有豐富經驗的朋友進來看一個boost.asio通訊的問題 955錯誤

請對socket程式設計有豐富經驗的朋友進來看一個boost.asio通訊的問題 955錯誤

論壇首頁 精選版塊 論壇牛人 排行榜 論壇地圖 我要發貼

論壇幫助

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客服[email protected]客服論壇工作時間 8:00-22:00400-660-0108工作時間8:00-19:00

百度提供站內搜尋 京ICP證09002463號

©2018 北京創新樂知資訊科技有限公司版權所有

經營性網站備案資訊 網路110報警服務 中國網際網路舉報中心 北京網際網路違法和不良資訊舉報中心