I'm trying to port my IRC bot from Python to C++ and I'm running into some issues with Winsock2. I'm fairly new to sockets in C/C++ and most of this code was pieced together from various tutorials. I keep getting error 10049 and am at a loss. Any help would be appreciated greatly. Thanks!
port_ is set to 6667 and host_ is "irc.rizon.net"
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "WSAStartup Successful!" << std::endl;
socketfd_ = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (socketfd_ == INVALID_SOCKET) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "Socket Creation Successful!" << std::endl;
sockaddr_in anews;
anews.sin_port = htons(port_);
anews.sin_addr.s_addr = inet_addr(host_.c_str());
anews.sin_family = AF_INET;
if (connect(socketfd_,(sockaddr*)&anews, sizeof(anews)) == SOCKET_ERROR) {
std::cout << "Error: " << WSAGetLastError() << " occurred!" << std::endl;
WSACleanup();
return 1;
}
std::cout << "Socket has connected successfuly!" << std::endl;
return 0;
inet_addr() takes a dotted IP address of the form "x.x.x.x" you are passing it the host name.
You can use gethostbyname():
hostent* host;
char* ip;
...
// Get the local host information
host= gethostbyname(host_.c_str());
ip= inet_ntoa(*(struct in_addr *)*host->h_addr_list);
sockaddr_in anews;
anews.sin_port = htons(port_);
anews.sin_addr.s_addr = inet_addr(ip);
anews.sin_family = AF_INET;
...
Or an easier route would be to use getaddrinfo():
struct addrinfo *ai;
if(getaddrinfo(host_.c_str(), "6667", NULL, &ai) != 0)
return 1;
socketfd_ = socket(ai->ai_family, SOCK_STREAM, 0);
if (socketfd_ == INVALID_SOCKET) {
freeaddrinfo(ai);
return 1
}
if (connect(socketfd_, ai->ai_addr, (int)ai->ai_addrlen) == SOCKET_ERROR) {
closesocket(socketfd_);
freeaddrinfo(ai);
return 1;
}
...
Related
I am implementing a tcp server and client using secure sockets (Poco::Net::SecureServerSocket), I attach here the code I am using:
void serverClientTest()
{
try {
Poco::Net::initializeSSL();
// Socket server
Poco::Net::Context::Ptr ptrContext =
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE,
"./cert4/myKey.pem",
"./cert4/myCert.pem",
"./cert4/myCert.pem",
Poco::Net::Context::VERIFY_ONCE);
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert = new Poco::Net::AcceptCertificateHandler(true);
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler> ptrPrivateKeyPassphraseHandler;
ptrPrivateKeyPassphraseHandler = new Poco::Net::KeyConsoleHandler(true);
Poco::Net::SSLManager::instance().initializeServer(ptrPrivateKeyPassphraseHandler, ptrCert, ptrContext);
Poco::Net::SocketAddress serverAddress("0.0.0.0", 8085);
Poco::Net::SecureServerSocket serverSecureSocket(serverAddress);
Poco::Net::TCPServer srv(new Poco::Net::TCPServerConnectionFactoryImpl<EchoConnection>(), serverSecureSocket);
srv.start();
Poco::Net::Context::Ptr ptrContext2 =
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
"./cert4/myKey.pem",
"./cert4/myCert.pem",
"./cert4/myCert.pem",
Poco::Net::Context::VERIFY_ONCE);
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert2 = new Poco::Net::AcceptCertificateHandler(true);
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler>ptrPrivateKeyPassphraseHandler2(new Poco::Net::KeyConsoleHandler(false));
Poco::Net::SSLManager::instance().initializeClient(ptrPrivateKeyPassphraseHandler2, ptrCert2, ptrContext2);
Poco::Net::SocketAddress sa("127.0.0.1", 8085);
Poco::Net::SecureStreamSocket ss1(sa);
std::string data("TEST TEST");
int retSend = ss1.sendBytes(data.data(), (int) data.size());
if (retSend>0)
{
std::cout << "buffer -> : " << data.data() << std::endl;
char buffer[1024];
memset(buffer, '\0', 1024);
int retRecv = ss1.receiveBytes(buffer, sizeof(buffer));
if (retRecv > 0)
{
std::cout << "buffer <- : " << buffer << std::endl;
}
else
{
std::cout << "ERROR: recv " << retRecv << std::endl;
}
}
ss1.close();
}
catch (Poco::Exception& ex)
{
std::cout << "!! EXCEPTION "<< ex.displayText() << std::endl;
}
}
//[....]
class EchoConnection: public Poco::Net::TCPServerConnection
{
public:
EchoConnection(const Poco::Net::StreamSocket& s): Poco::Net::TCPServerConnection(s){}
void run()
{
Poco::Net::StreamSocket& ss = socket();
std::cout << "connection from client: " << ss.address() << std::endl;
try
{
// ...
}
catch (Poco::Exception& exc)
{
std::cerr << "--------------- EchoConnection: " << exc.displayText() << std::endl;
}
}
};
I would like the server to close the connection if the client certificate is not known to the server, but it happens
which, even with the context:
Poco::Net::Context::Ptr ptrContext2 =
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
"",
"",
"./cert4/myCert.pem",
Poco::Net::Context::VERIFY_ONCE);
Thanks to anyone who can help me out.
void serverClientTest()
{
try {
Poco::Net::initializeSSL();
// Socket server
Poco::Net::Context::Ptr ptrContext =
new Poco::Net::Context(Poco::Net::Context::SERVER_USE,
"./server.key",
"./server.crt",
"./ca.pem",
Poco::Net::Context::VERIFY_STRICT,
9,
false,
"ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH");
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert = new Poco::Net::AcceptCertificateHandler(true);
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler> ptrPrivateKeyPassphraseHandler;
ptrPrivateKeyPassphraseHandler = new Poco::Net::KeyConsoleHandler(true);
Poco::Net::SSLManager::instance().initializeServer(ptrPrivateKeyPassphraseHandler, ptrCert, ptrContext);
Poco::Net::SocketAddress serverAddress("0.0.0.0", 8085);
Poco::Net::SecureServerSocket serverSecureSocket(serverAddress);
Poco::Net::TCPServer srv(new Poco::Net::TCPServerConnectionFactoryImpl<EchoConnection>(), serverSecureSocket);
srv.start();
Poco::Net::Context::Ptr ptrContext2 =
new Poco::Net::Context(Poco::Net::Context::CLIENT_USE,
"./client.key",
"./client.crt",
"./ca.pem",
Poco::Net::Context::VERIFY_STRICT,
9,
true,
"ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH");
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrCert2 = new Poco::Net::AcceptCertificateHandler(true);
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler>ptrPrivateKeyPassphraseHandler2(new Poco::Net::KeyConsoleHandler(false));
Poco::Net::SSLManager::instance().initializeClient(ptrPrivateKeyPassphraseHandler2, ptrCert2, ptrContext2);
Poco::Net::SocketAddress sa("127.0.0.1", 8085);
Poco::Net::SecureStreamSocket ss1(sa);
std::string data("TEST");
int retSend = ss1.sendBytes(data.data(), (int) data.size());
if (retSend>0)
{
char buffer[1024];
memset(buffer, '\0', 1024);
int retRecv = ss1.receiveBytes(buffer, sizeof(buffer));
if (retRecv > 0)
{
std::cout << "buffer <-: " << buffer << std::endl;
}
else
{
std::cout << "ERROR: " << retRecv << std::endl;
}
}
ss1.close();
}
catch (Poco::Exception& ex)
{
std::cout << ex.displayText() << std::endl;
}
}
I am a beginner at the socket programming level that's why I found some problems that may be simple. I tried to send a simple message from client to server but the command send return (-1) that's why the message not received by the server.
Also, I have the same problem in the server code and the receiver command. return (-1).
Following is my client code :
bool ClientSock() {
int sock;
struct sockaddr_in address;
sock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10102);
if (connect(sock, (struct sockaddr*) &address, sizeof (address)) < 0) {
cout << "connect failed. Error \n";
return 0 ;
} else
return 1;
}
void SendComm() {
long ok;
char MESSAGE [2000];
string msg;
cout << "enter message:\t";
cin>> msg;
const char * s = msg.c_str();
int sock;
ok = send(sock, s, 1024, 0);`enter code here`
if ( send(sock,s,1024,0)< 0){//this is the problem
std::cout << "you can not send the message";
}
else{
ok = recv(sock, MESSAGE, sizeof (MESSAGE), 0);
string reply;
reply = MESSAGE;
cout << "server says:_t" << reply << endl;
}
}
int main() {
if (ClientSock()==1){
SendComm();
}
else
std::cout << "error";
}
This is my server code:
bool initialize() {
int conSock;
int ListenSock;
socklen_t addrsize;
struct sockaddr_in address;
addrsize = sizeof (address);
conSock = socket(AF_INET, SOCK_STREAM, 0);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10102);
ListenSock = socket(AF_INET, SOCK_STREAM, 0);
bind(ListenSock, (sockaddr *) & address, sizeof (address));
listen(ListenSock, SOMAXCONN);
std::cout << "server waiting for connexion\n\n ";
if (conSock = accept(ListenSock, (struct sockaddr *) &address, &addrsize) < 0) {
cout << "connect failed. Error";
return 0;
} else
return 1;
}
void Communicate() {
int conSock;
int ListenSock;
struct sockaddr_in address;
socklen_t addrsize;
long ok;
char MESSAGE[2000];
ok = recv(conSock, MESSAGE, sizeof (MESSAGE), 0);
if (recv(conSock, MESSAGE, sizeof (MESSAGE), 0)< 0){
std:: cout << "No message" ;
}
else{
string msg;
msg = MESSAGE;
cout << " client says:\t" << msg << endl;
string reply;
cout << "enter reply:\t";
cin>> reply;
const char* s = reply.c_str();
ok = send(conSock, s, 1024, 0);
}}
int main() {
if (initialize() == 1) {
Communicate();
} else
std::cout << "error ";
}
I am trying to create a server/client communication console, but once i include the external libraries (cryptopp) and debug, it will always terminate due socket invalid error. I have no idea what is going on.
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
#include "../cryptopp565/sha.h"
using CryptoPP::SHA1;
using namespace std;
int main()
{
//initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
cerr << "Can't Initialize winsock! program terminate." << endl;
return 1;
}
//create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! program terminate." << endl;
return 1;
}
//Promtp to get server port
string server_port_temp;
cout << "Enter port : ";
cin >> server_port_temp;
int server_port = stoi(server_port_temp);
//bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(server_port);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
cerr << "Invalid socket ! program terminate." << endl;
return 1;
}
char host[NI_MAXHOST]; //client remote name
char service[NI_MAXHOST]; // service (poet client is connect on)
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXHOST, 0) == 0)
{
cout << host << " Connect on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " Connected on port " << ntohs(client.sin_port) << endl;
}
//close listening socket
closesocket(listening);
//while loop: communication
char buf[4096];
//communicate ________________
while (true)
{
ZeroMemory(buf, 4096);
//wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
cerr << "Error in recv(). Program terminate." << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected " << endl;
break;
}
cout << string(buf, 0, bytesReceived) << endl;
//echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
}
//close the socket
closesocket(clientSocket);
//clean winsock
WSACleanup();
system("pause");
return 0;
}`
There is the code i am trying to implement in a client/server model but segmentation fault error is coming..
server:
/* this is the structure i am trying to pass*/
struct pkt{
char data[1000];
int seqNo;
int checksum;
void make_pkt(int seq,char dat[1000],int check)
{
seqNo=seq;
strcpy(data,dat);
checksum=check;
}
};
the main part is
main() /* main */
{
port=client_addr.sin_port;
cout<<"port : "<<port;
pkt *rcv=new pkt;
do{
cout<<"a"<<endl;
cout<<"port : "<<port;
pkt *newpkt=new pkt;
char *buffer=new char [1000];
strcpy(buffer,"Hamza");
newpkt->make_pkt(1,buffer,2);
cout<<"aa"<<endl;
client_addr.sin_port=port;
cout<<"port 2 : "<<client_addr.sin_port<<endl;
sendto(sockfd,&newpkt,sizeof(struct pkt),0,(struct sockaddr *) &client_addr,sizeof(client_addr));
cout<<"aaa"<<endl;
recvfrom(sockfd,&rcv,sizeof(struct pkt),0,(struct sockaddr *)&client_addr,&leng);
cout<<"bb :"<<rcv->seqNo<<endl;
}while(rcv->seqNo!=1);
}
client:
struct pkt{
char data[1000];
int seqNo;
int checksum;
pkt()
{
strcpy(data," ");
seqNo=0;
timer=0;
checksum=0;
}
};
main()
{
pkt *newpkt=new pkt;
do{
cout<<"aa"<<endl;
pkt *rcvpkt=new pkt;
socklen_t lengt=sizeof(my_addr);
recvfrom(sockfd,&rcvpkt,sizeof(struct pkt),0,(struct sockaddr *)&my_addr,&lengt);
cout<<"aaa"<<endl;
cout<<"aaa"<<rcvpkt->data<<endl;
newpkt->seqNo=1;
sendto(sockfd,&newpkt,sizeof(struct pkt),0,(struct sockaddr *) &my_addr,sizeof(my_addr));
}while(newpkt->seqNo!=1);
}
please tell me whats the problem in this code..?
You are not passing the struct instances to sendto() and recvfrom() correctly. Your pkt variables are pointers so you need to get rid of the & operator when passing them. You also have memory leaks. Try this instead:
main()
{
port = ntohs(client_addr.sin_port);
cout << "port : " << port;
pkt *rcv = new pkt;
do{
cout << "a" << endl;
cout << "port : " << port;
pkt *newpkt = new pkt;
char buffer[1000];
strcpy(buffer,"Hamza");
newpkt->make_pkt(1,buffer,2);
cout << "aa" << endl;
client_addr.sin_port = htons(port);
cout << "port 2 : " << ntohs(client_addr.sin_port) << endl;
sendto(sockfd, newpkt, sizeof(struct pkt), 0, (struct sockaddr *) &client_addr, sizeof(client_addr));
delete newpkt;
cout << "aaa" << endl;
recvfrom(sockfd, rcv, sizeof(struct pkt), 0, (struct sockaddr *)&client_addr, &leng);
cout << "bb :" << rcv->seqNo << endl;
}
while(rcv->seqNo != 1);
delete rcv;
}
main()
{
pkt *newpkt = new pkt;
do{
cout << "aa" << endl;
pkt *rcvpkt = new pkt;
socklen_t lengt = sizeof(my_addr);
recvfrom(sockfd, rcvpkt, sizeof(struct pkt), 0, (struct sockaddr *)&my_addr, &lengt);
cout << "aaa" << endl;
cout << "aaa" << rcvpkt->data << endl;
newpkt->seqNo = 1;
sendto(sockfd, newpkt, sizeof(struct pkt), 0, (struct sockaddr *) &my_addr, sizeof(my_addr));
delete rcvpkt;
}
while(newpkt->seqNo != 1);
delete newpkt;
}
So I configured windows 8 firewall to allow IPV6 outbound and inbound connections as a precautionary measure but whenever I try to connect to either are remote host or to my own machine using the loopback address(to an ipv6 server application running simultaneously)the connect function FAILS with error 10049 regardless of what port I choose. Is this a network configuration problem? IP4 works just fine.
#include "stdafx.h"
#include <iostream>
#include <iostream>
#include <string>
#include <stdlib.h>
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <WS2tcpip.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <IPTypes.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib,"iphlpapi.lib")
using namespace std;
static int MAXPENDING = 5;
void set_interface(SOCKET s, DWORD Index);
int main(int argc,char* argv[])
{
WSADATA wsaData;
int Result;
int optv = 1;
char *optval = (char*)&optv;
int optlen = sizeof(optval);
DWORD Index = 22;
bool connected = false;
string exit = "quit";
string name;
sockaddr_in6 c_addr;
c_addr.sin6_family = AF_INET6;
char buffer[1024];
Result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (Result != NO_ERROR) {
printf("WSAStartup function failed with error: %d\n", GetLastError());
return 0;
}
SETUP:
SOCKET connector;
connector = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (connector == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
closesocket(connector);
return 1;
}
cout << "Enter host name(URL): ";
cin >> name;
cout << endl;
char *hostname = const_cast<char*>(name.c_str());
if(inet_pton(AF_INET6,hostname,&c_addr.sin6_addr)<0){
printf("InetPton() function failed with error: %d/n",GetLastError());
closesocket(connector);
return 1;
}
string p;
char *hostport;
int p0rt;
cout << "Enter the port number you wish to connect on: " ;
cin >> p;
cout << endl;
hostport = const_cast<char*>(p.c_str());
p0rt = atoi(hostport);
if(!( 0 < p0rt && p0rt < 65,536)){
cout << "Error: port number must be greater than 0 and less than 65,536. " << endl;
cout << endl;
cout << "Re-enter the port number you wish to connect on: " ;
cin >> p;
cout << endl;
hostport = const_cast<char*>(p.c_str());
p0rt = atoi(hostport);
}else{
c_addr.sin6_port = htons(p0rt);
}
if(connect(connector,(sockaddr*)&c_addr,sizeof(c_addr))<0){
printf("Connect failed with error: %d\n",GetLastError());
string cmd;
cout << endl;
cout <<"Try again? Type 'y' to reattempt connection or type any other key to exit: ";
cin >> cmd;
cout << endl;
if(cmd=="y"){
goto SETUP;
}else {
goto QUIT;
}
}else{
connected = true;
cout << "Connected to host " << hostname << " on port " << c_addr.sin6_port << endl;
cout << "Type 'quit' to exit the program " << endl;
}
while(connected==true){
int nbr = 0;
cout << endl;
cout << ">";
scanf("%s",buffer);
cout << endl;
string str(buffer);
if(str==exit){
connected = false;
goto QUIT;
}
long nbs = send(connector,buffer,sizeof(buffer),0);
if(nbs < 0){
printf("send() failed", GetLastError());
goto QUIT;
}
while(nbr < nbs){
nbr = recv(connector,buffer,sizeof(buffer),0);
if(nbr < 0){
printf("recv() failed", GetLastError());
goto QUIT;
}else if(nbr==0){
printf("recv() failed: connection closed prematurely", GetLastError());
goto QUIT;
}else if(nbr > 0){
cout << endl;
cout << ">> ";
printf(buffer);
cout << endl;
}
}
}
QUIT:
if (closesocket(connector) == SOCKET_ERROR) {
printf("closesocket function failed with error: %ld\n", GetLastError());
WSACleanup();
return 1;
}
WSACleanup();
return 0;
};
void set_interface(SOCKET s, DWORD Index){
MIB_IF_ROW2 T2;
NET_LUID ID;
DWORD ptbuflen = (DWORD)sizeof(T2);
ConvertInterfaceIndexToLuid(Index,&ID);
T2.InterfaceLuid = ID;
GetIfEntry2(&T2);
if(WSAIoctl(s,SIO_ASSOCIATE_HANDLE,&T2,ptbuflen,NULL,0,0,NULL,NULL)>0){
printf("WSAIoctl() function failed with error: %d\n", GetLastError());
closesocket(s);
}
if(WSAIoctl(s,SIO_TRANSLATE_HANDLE,&T2,ptbuflen,NULL,0,0,NULL,NULL)>0){
printf("WSAIoctl() function failed with error: %d\n", GetLastError());
closesocket(s);
}
};
You need to zero out the portion of the sockaddr_in6 that you are not using. Zero out the enire thing first, then fill in the portions you need.
If the user fails to enter a valid port the first time, you are not validating the new port entered the second time, and you are not assigning that second port value to the sockaddr_in6 at all. You should be doing your validation in a loop, and then assign the final accepted value to the sockaddr_in6.
You are using inet_pton() when you should be using getaddrinfo() instead. inet_pton() only converts an IP address string to its binary format. It will not resolve a hostname to an IP. getaddrinfo() does that resolution instead, and it also supports converting IP address strings as well (specify the AI_NUMERICHOST flag in the hints parameter to get that behavior).