Я пытаюсь написать сетевую программу с использованием инструментов сокета 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 ++ и другие алгоритмы криптографии.Но я не могу правильно отправить данные между сервером и клиентом.
Ниже приведен мой код.
Код сервера:
#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 позволяет отправлять данные только один раз?Кто может мне сказать?
Спасибо, очень-очень жутко.
Я нашел похожий вопрос: CryptoPP: как использовать SocketSource и SocketSink