我正在尝试使用crypto ++的套接字工具编写网络程序。但是它总是无法正常工作。
问题1:
我想写两个程序。一是服务器。另一个是客户。服务器可以多次向客户端发送大量数据。
以下是我的代码。
服务器代码:
#include<iostream>
#include<socketft.h>
#include<string>
using namespace std;
using namespace CryptoPP;
int main()
{
try
{
Socket::StartSockets();//strating sockets
Socket socServer;
socServer.Create(SOCK_STREAM);//create a socket's object
unsigned int iport;
string send_str;
cout << "input port:" ;
cin >> iport;
socServer.Bind(iport);//binding
socServer.Listen();//listening
Socket socClient;//client's socket
socServer.Accept(socClient);//accept
while(true)
{
cout << "input string:" ;
cin >> send_str;
//cin.clear();
//getline(cin,send_str);
StringSource str_send_Src1(send_str,true,new SocketSink(socClient));
}
/*
cout << "input string:" ;
cin >> send_str;
StringSource str_send_Src1(send_str,true,new SocketSink(socClient));
cout << "input string:" ;
cin >> send_str;
StringSource str_send_Src2(send_str,true,new SocketSink(socClient));
*/
socServer.CloseSocket();
socClient.CloseSocket();
Socket::ShutdownSockets();
}
catch(const Exception& e)
{
cout << e.what() << endl;
}
return 0;
}
客户代码:
#include<iostream>
#include<socketft.h>
#include<string>
using namespace std;
using namespace CryptoPP;
int main()
{
try
{
Socket::StartSockets();
Socket socClient;
socClient.Create(SOCK_STREAM);
string straddr;
unsigned int iport;
cout << "input connecting ip:" ;
cin >> straddr;
cout << "input connecting port:" ;
cin >> iport;
socClient.Connect(straddr.c_str(),iport);//connecting
while(true)
{
string receive;
SocketSource receiverSrc(socClient.GetSocket(),true,new StringSink(receive));
cout << receive ;
}
socClient.CloseSocket();
Socket::ShutdownSockets();
}
catch(const Exception& e)
{
cout << e.what() << endl;
}
return 0;
}
问题是:
在启动服务器然后启动客户端时,它们将正确运行。但是,我只能输入一次数据。然后服务器被卡住,不接受任何输入。
如何解决?谁可以帮助我?
问题2:
我想使用crypto ++的套接字和其他cryptograpy算法构造一个安全通道。但是我无法在服务器和客户端之间正确发送数据。
以下是我的代码。
服务器代码:
#include<iostream>
#include<socketft.h>
#include<files.h>
#include<osrng.h>
#include<string>
#include<tiger.h>
#include<eccrypto.h>
#include<integer.h>
#include<dh.h>
#include<hex.h>
using namespace std;
using namespace CryptoPP;
int main()
{
try
{
//server
Socket::StartSockets();
Socket socServer;
socServer.Create(SOCK_STREAM);
unsigned int iport;
string filename;
cout << "input port:" ;
cin >> iport;
//iport = 5050;
socServer.Bind(iport);
socServer.Listen();
Socket socClient;
socServer.Accept(socClient);
string testStr = "you have connected...";
StringSource testSenSrc(testStr,true,new SocketSink(socClient.GetSocket()));
SocketSource testRecSrc(socClient.GetSocket(),true,new StringSink(testStr));
cout << "client'"+testStr+" have connected...";
AutoSeededRandomPool rng;
ECDSA<ECP,Tiger>::PrivateKey prikey_server;
prikey_server.Load(
FileSource("sin_prikey_server.der",true).Ref());
ECDSA<ECP,Tiger>::PublicKey pubkey_client;
pubkey_client.Load(
FileSource("sin_pubkey_client.der",true).Ref());
ECDSA<ECP,Tiger>::Signer sig_server(prikey_server);
ECDSA<ECP,Tiger>::Verifier ver_client(pubkey_client);
Integer p("B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
"DF1FB2BC2E4A4371h");
Integer g("A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
"855E6EEB22B3B2E5h");
Integer q("F518AA8781A8DF278ABA4E7D64B7CB9D49462353h");
DH dh(p,q,g);
SecByteBlock dh_prikey_server(dh.PrivateKeyLength());
SecByteBlock dh_pubkey_server(dh.PublicKeyLength());
dh.GenerateKeyPair(rng,dh_prikey_server,dh_pubkey_server);
ArraySource Sig_dh_pubkey_Src(
dh_pubkey_server,dh_pubkey_server.size(),true,
new SignerFilter(rng,sig_server,
new SocketSink(socClient),true));
SecByteBlock dh_pubkey_client(dh.PublicKeyLength());
SocketSource ArrSrc(socClient,true,
new SignatureVerificationFilter(ver_client,
new ArraySink(dh_pubkey_client,dh_pubkey_client.size()),
SignatureVerificationFilter::SIGNATURE_AT_END
|SignatureVerificationFilter:: PUT_MESSAGE));
SecByteBlock agreedkey(dh.AgreedValueLength());
boolbResult=dh.Agree(
agreedkey,dh_prikey_server,dh_pubkey_client);
if(bResult)
cout << "key aggrement success..." << endl;
else
{
throw Exception(Exception::INVALID_ARGUMENT,
"key aggrement failure...");
}
socServer.CloseSocket();
socClient.CloseSocket();
Socket::ShutdownSockets();
}
catch(const Exception& e)
{
cout << e.what() << endl;
}
return 0;
}
客户代码:
#include<iostream>
#include<socketft.h>
#include<files.h>
#include<string>
#include<osrng.h>
#include<files.h>
#include<tiger.h>
#include<eccrypto.h>
#include<integer.h>
#include<dh.h>
#include<hex.h>
#include<secblock.h>
using namespace std;
using namespace CryptoPP;
int main()
{
try
{
//Client
Socket::StartSockets();
Socket socClient;
socClient.Create(SOCK_STREAM);
string straddr;
unsigned int iport;
cout << "input ip:" ;
cin >> straddr;
//straddr = "127.0.0.1";
cout << "input port:" ;
cin >> iport;
//iport = 5050;
socClient.Connect(straddr.c_str(),iport);
StringSource testSenSrc(straddr,true,
new SocketSink(socClient));
string testStr;
SocketSource testRecSrc(socClient,true,
new StringSink(testStr));
cout << testStr << endl;
AutoSeededRandomPool rng;
ECDSA<ECP,Tiger>::PrivateKey prikey_client;
prikey_client.Load(
FileSource("sin_prikey_client.der",true).Ref());
ECDSA<ECP,Tiger>::PublicKey pubkey_server;
pubkey_server.Load(
FileSource("sin_pubkey_server.der",true).Ref());
ECDSA<ECP,Tiger>::Signer sig_client(prikey_client);
ECDSA<ECP,Tiger>::Verifier ver_server(pubkey_server);
Integer p("B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
"9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
"13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
"98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
"A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
"DF1FB2BC2E4A4371h");
Integer g("A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
"D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
"160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
"909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
"D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
"855E6EEB22B3B2E5h");
Integer q("F518AA8781A8DF278ABA4E7D64B7CB9D49462353h");
DH dh(p,q,g);
SecByteBlock dh_prikey_client(dh.PrivateKeyLength());
SecByteBlock dh_pubkey_client(dh.PublicKeyLength());
dh.GenerateKeyPair(rng,dh_prikey_client,dh_pubkey_client);
ArraySource Sig_dh_pubkey_Src(
dh_pubkey_client,dh_pubkey_client.size(),true,
new SignerFilter(rng,sig_client,
new SocketSink(socClient.GetSocket()),true));
SecByteBlock dh_pubkey_server(dh.PublicKeyLength());
SocketSource ArrSrc(socClient,true,
new SignatureVerificationFilter(ver_server,
new ArraySink(dh_pubkey_server,dh_pubkey_server.size()),
SignatureVerificationFilter::SIGNATURE_AT_END
|SignatureVerificationFilter:: PUT_MESSAGE));
SecByteBlock agreedkey(dh.AgreedValueLength());
boolbResult=dh.Agree(
agreedkey,dh_prikey_client,dh_pubkey_server);
if(bResult)
cout << "key agreement success..." << endl;
else
{
throw Exception(Exception::INVALID_ARGUMENT,
"key agreement failure...");
}
socClient.CloseSocket();
Socket::ShutdownSockets();
}
catch(const Exception& e)
{
cout << e.what() << endl;
}
return 0;
}
问题是:
启动服务器时,然后启动客户端,它将无法正常工作。但是,当我在服务器和客户端中删除一些代码时,它将显示“密钥协议成功...”。
以下是从服务器中删除的代码。
string testStr = "you have connected...";
StringSource testSenSrc(testStr,true,new
SocketSink(socClient.GetSocket()));
SocketSource testRecSrc(socClient.GetSocket(),true,new
StringSink(testStr));
cout << "client'"+testStr+" have connected...";
以下是从客户端删除的代码。
StringSource testSenSrc(straddr,true,
new SocketSink(socClient));
string testStr;
SocketSource testRecSrc(socClient,true,
new StringSink(testStr));
cout << testStr << endl;
它类似于第一个问题。因为第二个问题是由“两次发送和接收”引起的。删除上述代码后,它可以正常运行。
SocketSink只允许发送一次数据吗?谁能告诉我?
非常非常感谢。
答案 0 :(得分:1)
正如jww所说,我们应该放弃crypto ++的网络工具。因为它很旧,总是会引起问题。我们可以尝试libevent,asio等。
以下链接向您展示了一些有关c ++的网络库。