I can't receive message in multicast by my server however the sending is good I think, I supposed I messed with the IP's but don't know how to solve this.
Here is my testClient:
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <mutex>
#include <thread>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
struct in_addr localInterface;
struct sockaddr_in groupSock;
socklen_t groupSockLength;
int sd;
uint8_t databuf[5000] ;
int datalen = sizeof(databuf);
std::ofstream MyFile("TestAppliMsgReceive.txt");
ssize_t resRecv;
int main (int argc, char *argv[ ])
{
/* Create a datagram socket on which to send. */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd < 0)
{
perror("Opening datagram socket error");
exit(1);
}
else
std::cout<<"Opening the datagram socket...OK.\n"<<std::endl;
/* Initialize the group sockaddr structure with a */
/* group address of 225.1.1.1 and port 5555. */
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
groupSock.sin_addr.s_addr = inet_addr("224.10.1.0");
groupSock.sin_port = htons(50000);
localInterface.s_addr = inet_addr("10.16.2.1");
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
{
perror("Setting local interface error");
exit(1);
}
else
std::cout<<"Setting the local interface...OK\n"<<std::endl;
/* Send a message to the multicast group specified by the*/
/* groupSock sockaddr structure. */
if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock, sizeof(groupSock)) < 0)
{perror("Sending datagram message error");}
else
std::cout<<"Sending datagram message...OK\n"<<std::endl;
while(1){
std::cout<<"Which kind of message do you want to send?"<<std::endl;
std::cout<<" [1] Custom message "<<std::endl;;
int choice;
std::cin>>choice;
if (choice==1) {
std::cout<<"enter msg\n";
std::cin>>databuf;
datalen = sizeof(databuf);
sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock, sizeof(groupSock));
}
}
return 0;
}
and here the server side, Maybe the problem is more here than in the client:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <string>
#include <list>
#include <mutex>
#include <thread>
//-------------------------------------------------------------------------------------------------
// Definition of variables common to all functions in the AppliMsg thread
//-------------------------------------------------------------------------------------------------
static char logInfoText[LOG_TEXT_SIZE]; // Text buffer for supervision log
static int localSockDesc; // Descriptor of the socket to the client application
static struct sockaddr_in localSockAddr; // IP address and port binded to the AppliMsg socket
static struct sockaddr_in mcastSockAddr; // Destination multicast address and port
//-------------------------------------------------------------------------------------------------
// Init of AppliMsg thread
//-------------------------------------------------------------------------------------------------
void AppliMsgInit()
{
std::string stgNetCastAddr; // Netcast IP address as a string
std::string stgNeighCastAddr; // Neighbourcast IP address as a string
std::string stgLocalIpAddr; // Ethernet interface IP address as a string
uint16_t localPortNum; // Port number of the Ethernet interface
struct ip_mreq ipMcast; // Multicast configuration
unsigned int numMcastTtl; // TTL definition
int sockFlags; // Flags of the socket
// Destination multicast address and port
mcastSockAddr.sin_family=AF_INET;
mcastSockAddr.sin_addr.s_addr=inet_addr("224.10.2.1");
mcastSockAddr.sin_port=htons(50000);
// Create the socket
localSockDesc = socket(AF_INET, SOCK_DGRAM, 0);
// Configure the socket for multicast capability and non-blocking reception
numMcastTtl = MCAST_TTL;
setsockopt(localSockDesc , IPPROTO_IP, IP_MULTICAST_TTL, (char *)&numMcastTtl, sizeof(numMcastTtl));
sockFlags = fcntl(localSockDesc, F_GETFL);
fcntl(localSockDesc, F_SETFL, sockFlags | O_NONBLOCK);
// Bind the Ethernet interface IP address and port to the socket
localSockAddr.sin_family=AF_INET;
localSockAddr.sin_addr.s_addr=inet_addr("10.16.2.1");
// localSockAddr.sin_addr.s_addr=INADDR_ANY; //SIMDEBUG
localSockAddr.sin_port=htons(50000);
// Bind the Ethernet IP address to the socket
if (bind(localSockDesc,(struct sockaddr *) &localSockAddr,sizeof(localSockAddr)) < 0)
{
// Error case
}
// Subscribe to the multicast server
ipMcast.imr_multiaddr.s_addr = inet_addr("224.10.2.1");
ipMcast.imr_interface.s_addr = inet_addr("10.16.2.1");
setsockopt(localSockDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipMcast, sizeof(ipMcast));
}
//-------------------------------------------------------------------------------------------------
// Main function of the AppliMsg thread
//-------------------------------------------------------------------------------------------------
int AppliMsgWait()
{
std::string stgLocalIpAddr;
std::string stgNetCastAddr; // Netcast IP address as a string
std::string stgNeighCastAddr; // Neighbourcast IP address as a string
struct ip_mreq ipMcast; // Multicast configuration
// Main loop to process events from the simulated channel and the client application
while (1)
{
// Check the update flag in the Configuration Context
if (objConfigCtx.ConfigCtxGetFlagChangeAddr_()==true)
{
// Update the multicast configuration of the socket
ipMcast.imr_multiaddr.s_addr = inet_addr("224.10.1.0");
ipMcast.imr_interface.s_addr = inet_addr("10.16.2.1");
setsockopt(localSockDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&ipMcast, sizeof(ipMcast));
}
// Check the presence and receive of a message from the client application
AppliMsgRecvSCOM();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
return 1;
}
//-------------------------------------------------------------------------------------------------
// Check the presence and receive of a message from the client application
//-------------------------------------------------------------------------------------------------
void AppliMsgRecvSCOM()
{
struct sockaddr_in sourceSockAddr; // Sender IP address
socklen_t sourceSockAddrLength; // Temporary structure length
stcDataTransmIndT msgDataTransmInd; // Structure of the internal message in the list
ssize_t resRecv; // Value returned by recv()
sourceSockAddrLength = sizeof(sourceSockAddr);
// Non-blocking receive for an application message sent by SCOM
resRecv=recvfrom(localSockDesc,msgDataTransmInd.msgData,sizeof(msgDataTransmInd.msgData),0,
(struct sockaddr *) &sourceSockAddr,&sourceSockAddrLength);
else if (resRecv > 0)
{
// An application message is received:
}
}
And I think the focused part is about the IP address I used.
Related
I'm new to c++ and need help.
I use an UDP server to receive structure however i have problem to read it , the client send a structure I call : ChannAccessReq so the structure is send and the server receive it with RECVFROM and I use a general structure by reading the header (H1) of the struct only and then i do a read when a condition is fullfill with a more precise structure (temp2) for the buffer. However the client need to send the message twice , the first time it goes until recvfrom and the second it reach read() (i think) I tried all the day and wonder if its the size of the buffer ?
I think the most sensitive part is in the server with the recvfrom() who have a struct different from the read() just after..
I hope it's clear!
here is the server :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "struct.h"
#include <iostream>
void DieWithError(char *err) {
perror(err);
exit(1);
}
typedef struct IntMsgHeaderType {
uint8_t code ; // Code message7
uint8_t bourrage ; // Octet de bourrage
uint16_t ParamLength; // Longueur eventuel données complémentaires
} HeaderInt;
typedef struct TextMessage //TESTTESTTEST
{
HeaderInt H; // Code message7
};
int main(int argc, char *argv[])
{
int sock; /* Socket */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned int cliAddrLen; /* Length of incoming message */
unsigned short echoServPort; /* Server port */
int recvMsgSize; /* Size of received message */
struct TextMessage * temp = (TextMessage *)malloc(sizeof(struct TextMessage));
HeaderInt *H1 =(HeaderInt *)malloc(104+sizeof(HeaderInt));
ChanAccesReq *temp2=(ChanAccesReq *)malloc(sizeof(ChanAccesReq));
if (!argv[1]) {
fprintf(stderr,"no port number provided");
exit(1);
}
echoServPort = atoi(argv[1]); /* First arg: local port */
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct local address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
echoServAddr.sin_port = htons(echoServPort); /* Local port */
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError("bind() failed");
for (;;) /* Run forever */
{
cliAddrLen = sizeof(echoClntAddr);
int nbrOctet;
if (recvfrom(sock, H1, sizeof(*H1), 0,(struct sockaddr *) &echoClntAddr, &cliAddrLen)>0 && H1->code==1){
//read(sock,H1,sizeof(*H1));
std::cout<<"taille nbrOctet : "<<nbrOctet<<'\n';
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
read(sock, temp2, sizeof(*temp2));
//read(sock,temp2,sizeof(*temp2))>0;
std::cout<<unsigned(temp2->P.linkAddr)<<'\n';
};
}
close(sock);
return 0;
}
and here the client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "struct.h"
void DieWithError(char *err) {
perror(err);
exit(1);
}
typedef struct {
char transMode ;
uint8_t linkAddr;
} ChanAccessReqParam;
typedef struct {
HeaderInt H;
ChanAccessReqParam P;
} ChanAccesReq ;
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
struct sockaddr_in fromAddr; /* Source address of echo */
unsigned short echoServPort; /* Echo server port */
unsigned int fromSize; /* In-out of address size for recvfrom() */
char *servIP; /* IP address of server */
int structLen; /* Length of string to echo */
int respStringLen; /* Length of received response */
if (!argv[1]) {
fprintf(stderr,"No server IP sepcified at arg 1\n");
exit(1);
}
else if (!argv[2]) {
fprintf(stderr,"No port Number Sepcified at arg 2\n");
exit(2);
}
ChanAccesReq test { 1 ,1,0,'c',15};
servIP = argv[1]; /* First arg: server IP address (dotted quad) */
echoServPort = atoi(argv[2]); /* Use given port, if any */
/* Create a datagram/UDP socket */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet addr family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
int tempint = 0;
tempint = sendto(sock, (ChanAccesInd*)&test, 10+(sizeof(test)), 0, (struct sockaddr *)
&echoServAddr, sizeof(echoServAddr));
if (tempint == -1 ) {
printf("Sent struct size: %d\n", tempint);
DieWithError("sendto() sent a different number of bytes than expected\n");
}
close(sock);
exit(0);
}
Thank you for your help
In C++ you have to define the type of the parameters.
As I deduced from the calling place, it should be int and bool.
int GesCanSlotSendTimeInd( int subscIPAddr , bool TransModeFlash){
return 0;
}
Also it is possible to use const qualifier, but you also need the type.
int GesCanSlotSendTimeInd( const int& subscIPAddr , const bool& TransModeFlash){
return 0;
}
For further info please look at cpp reference
You need to use non-blocking mode to poll for recvfrom and sendto at the same time. See here for more details.
int main(int argc, const char** argv) {
setvbuf(stdout, NULL, _IONBF, 0);
int portnum = 9988;
if (argc >= 2) {
portnum = atoi(argv[1]);
}
printf("Listening on port %d\n", portnum);
int sockfd = listen_inet_socket(portnum);
struct sockaddr_in peer_addr;
socklen_t peer_addr_len = sizeof(peer_addr);
int newsockfd = accept(sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len);
if (newsockfd < 0) {
perror_die("ERROR on accept");
}
report_peer_connected(&peer_addr, peer_addr_len);
// Set nonblocking mode on the socket.
int flags = fcntl(newsockfd, F_GETFL, 0);
if (flags == -1) {
perror_die("fcntl F_GETFL");
}
if (fcntl(newsockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror_die("fcntl F_SETFL O_NONBLOCK");
}
while (1) {
uint8_t buf[1024];
printf("Calling recv...\n");
int len = recv(newsockfd, buf, sizeof buf, 0);
if (len < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
usleep(200 * 1000);
continue;
}
perror_die("recv");
} else if (len == 0) {
printf("Peer disconnected; I'm done.\n");
break;
}
printf("recv returned %d bytes\n", len);
}
close(newsockfd);
close(sockfd);
return 0;
}
"A couple of notable differences from the blocking version:
The newsockfd socket returned by accept is set to nonblocking mode by calling fcntl.
When examining the return status of recv, we check whether errno is set to a value saying that no data is available for receiving. In this case we just sleep for 200 milliseconds and continue to the next iteration of the loop."
You can still send() and recvfrom() on the same socket since that you dont really need 2 differents process if that's what you need
I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile.The server is binded to localhost and port 8080. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.
Problem: The client is send the message and the server is receiving it correctly but the server is not able to return the message. Please help!
SERVER SIDE CODE:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main() {
int serSockDes, len, readStatus;
struct sockaddr_in serAddr, cliAddr;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
exit(-1);
}
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
cout<<len;
sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, len);
return 0;
}
CLIENT SIDE CODE:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main(int argc, char** argv) {
int cliSockDes, readStatus, len;
struct sockaddr_in serAddr;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr));
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
return 0;
}
The client is trying to send its message to INADDR_ANY, which is wrong. It needs to send to a specific IP address instead. The server can listen to all of its local IP addresses using INADDR_ANY, that is fine, but the IP address that the client sends to must be one that the server listens on (or, if the client and server are on different network segments, the client must send to an IP that reaches the server's router, which then must forward the message to an IP that the server is listening on).
Also, your calls to recvfrom() and sendto() on both ends are lacking adequate error handling. In particular, the addrlen parameter of recvfrom() specifies the max size of the sockaddr buffer upon input, and upon output returns the actual size of the peer address stored in the sockaddr. But you are not initializing the len variable that you pass in as the addrlen, so recvfrom() is likely to fail with an error that you do not handle.
Try something more like this instead:
Server:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main() {
int serSockDes, readStatus;
struct sockaddr_in serAddr, cliAddr;
socklen_t cliAddrLen;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if ((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if ((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
close(serSockDes);
exit(-1);
}
cliAddrLen = sizeof(cliAddr);
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, &cliAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(serSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
if (sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, cliAddrLen)) < 0) {
perror("sending error...\n");
close(serSockDes);
exit(-1);
}
close(serSockDes);
return 0;
}
Client:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main(int argc, char** argv) {
int cliSockDes, readStatus;
struct sockaddr_in serAddr;
socklen_t serAddrLen;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if ((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0) {
perror("sending error...\n");
close(cliSockDes);
exit(-1);
}
serAddrLen = sizeof(serAddr);
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, &serAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(cliSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
close(cliSockDes);
return 0;
}
Here I am checking UDP connection of IP address with specific port by using attached code. In my code if I give any IP and any port number it is getting connected successfully, the max range of port number is 5 digit but if I give more than 5 digit it will still get connection.
Major thing is on giving failure cases to check UDP Connection it passed that cases also.
failure cases i choosed:
1)not reachable IP
2)giving any port number
please help me to figure out what mistake i did in my code and what i can do in my code to check UDP connection is available for IP with specific port.My code attached below.
Thanks in Advance
#include <cstdlib>
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <string.h>
#include <unistd.h>
using namespace std;
int main()
{
int sockfd,rv;
struct addrinfo *servinfo, *p,hints;
struct sockaddr_in *h;
string host ="172.30.36.150";
int port=8997345;
memset(&hints, 0, sizeof hints);
struct sockaddr_in clientService;
int serversockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serversockfd == -1) {
fprintf(stderr, "Error in socket %d\n", errno);
}
clientService.sin_family = AF_INET;
rv = getaddrinfo( host.c_str() , NULL , &hints , &servinfo);
string strhost = "";
if(rv ==0){
p = servinfo;
h = (struct sockaddr_in *) p->ai_addr;
char chost[INET_ADDRSTRLEN];
strcpy(chost , inet_ntoa( h->sin_addr ) );
strhost.append(chost);
freeaddrinfo(servinfo);
}
clientService.sin_addr.s_addr = inet_addr(strhost.c_str());
clientService.sin_port = htons((u_short)port);
int res = connect(serversockfd, (struct sockaddr*) &clientService,
sizeof(clientService));
close(serversockfd);
if (res == -1) {
fprintf(stderr, "Error connecting socket %d\n", errno);
}else{
cout<<"successfully connected"<<endl;
}
}
I am implementing two way communications using UDP protocol , intitially i send a message HELO from client to server which successfully displays on server side but when i send message from server to client in reply of HELO so it gives me error: Address family not supported by protocol.
Here's my server code:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int main(void)
{
char write[100];
int MAXBUFLEN=100;
char* buf;
char msg[100];
char swp;
int l,x,y;
int conn_sock,n,err;
struct sockaddr_in server_addr,client_addr;
conn_sock=socket(AF_INET,SOCK_DGRAM,0);
if(conn_sock == -1)
{
perror("\n\nError in making socket and error is");
cout<<"Error No:\t\n"<<errno;
exit(0);
}
server_addr.sin_family= AF_INET;
server_addr.sin_port = 1234;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
err=bind(conn_sock,(struct sockaddr *)&server_addr,sizeof(server_addr)); // binding...
if(err == -1)
{
perror("\n\nError in binding and error is:");
cout<<"Error No:\t\n"<<errno;
exit(0);
}
int s=sizeof(client_addr);
n=recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,(socklen_t*)s); // reciving HELO from client..
cout<<msg<<endl;
cout<<"The messgae hasbeen recieved from client now enter a reply for HELO msg:"<<endl;
cin>> write;
// sending reply to client
int m=sendto(conn_sock,write,strlen(write),0,(sockaddr *)&client_addr,s); // sending reply to client on reply of helo...
if (m== -1){
perror("talker: sendto");
}
// now recieve mail fromm...
recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,(socklen_t*)s);
// sending rcpto client
sendto(conn_sock,write,strlen(write),0,(sockaddr *)&client_addr,s);
recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&client_addr,(socklen_t*)s);
cout<<"Recpt to: Nu.edu.pk"<<endl;
exit(0);
}
And here's my client code:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#define SERVERPORT "4950" // the port users will be connecting to
#define MAXBUFLEN 100
using namespace std;
int main(int argc, char*argv[])
{
// declarations
char msg3[]="DATA";
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
char buf[MAXBUFLEN];
socklen_t addr_len;
struct sockaddr_storage their_addr;
char* bigarray;
char msg[]="HELO";
char msg2[]="Mail from: Mahnoorfatima#gmail.com";
int i=0;
char * adress;
char * subject;
char * name;
const char *delim="#";
// getting commandline args into arrays.
adress=argv[i+1];
char* host=strtok(adress,delim );
subject=argv[i+2];
name=argv[i+3];
// putting all in one array
bigarray=adress;
bigarray=subject;
bigarray=name;
if(argc>9){
cout << "Just provide three arguments in commandline,please. " << endl;
}
// gets the name of the host:
int a=gethostname(bigarray, 100);
cout<<"The host of the client is:"<<a<<endl;
int conn_sock,n,m,err;
struct sockaddr_in server_addr;
conn_sock=socket(AF_INET,SOCK_DGRAM,0);
if(conn_sock ==-1)
{
perror("\n\nError in making socket and error is");
cout<<"Error No:\t\n"<<errno;
exit(0);
}
server_addr.sin_family= AF_INET;
server_addr.sin_port = 1234;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int pp=sizeof(server_addr);
n=sendto(conn_sock,msg,strlen(msg),0,(sockaddr *)&server_addr,pp);//sending HELO to server...
n=recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,(socklen_t*)pp);
cout<<"Mail from: mahnoorfatima22#gmail.com"<<endl;
n=sendto(conn_sock,msg2,strlen(msg2),0,(sockaddr *)&server_addr,pp);
// sending file to server
// reieving from server rcpto command
recvfrom(conn_sock,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,(socklen_t*)pp);
// sending data command to the server....
n=sendto(conn_sock,msg3,strlen(msg3),0,(sockaddr *)&server_addr,pp);
//Sending the filename to server...
if ((n = sendto(sockfd,name,strlen(name), 0,p->ai_addr, p->ai_addrlen)) == -1) {
// perror("Error is sending");
exit(1);
}
// Get the size of the file server sy
addr_len = sizeof their_addr;
if ((n = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
// perror("Error in recieving file");
exit(1);
}
cout<<"client: recieved file size: %s\nNumbytes:%d\n"<<buf<<numbytes;
exit(0);
}
The problem is most likely that the recvfrom function expects a pointer to the socket address structure size, while you provide the length by value. That means that the compiler with think that the size you set (sizeof(client_addr)) is interpreted as a pointer, and whatever the structure size is, it's not a valid pointer or pointing to something remotely valid.
That means that the recvfrom might not fill in the peer address structure (client_addr) completely, which leads to your sendto failure.
Try e.g. this instead:
n=recvfrom(conn_sock,msg,sizeof(msg),0,
(struct sockaddr *)&client_addr,&s);
// ^
// |
// Note address-of operator here
I was writing this simple client on Ubuntu 12. It is simple C/C++ connect to server code. It works connecting to localhost. But I can't get it to connect to an outside server. Everytime I connect to a different host, it actually connects to 'localhost'. I am thinking it might be the way my /etc/hosts file is configured but I don't know.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
int connect(const std::string host, const std::string path) {
const int port = 80;
// Setup the msock
int m_sock;
sockaddr_in m_addr;
memset(&m_addr, 0, sizeof(m_addr));
m_sock = socket(AF_INET, SOCK_STREAM, 0);
int on = 1;
if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof(on)) == -1) {
return false;
}
// Connect //
m_addr.sin_family = AF_INET;
m_addr.sin_port = htons(port);
int status = inet_pton(AF_INET, host.c_str(), &m_addr.sin_addr);
cout << "Status After inet_pton: " << status << " # " << m_addr.sin_addr.s_addr << endl;
if (errno == EAFNOSUPPORT) {
return false;
}
status = ::connect(m_sock, (sockaddr *) &m_addr, sizeof(m_addr));
if (status == -1) {
return false;
}
} // End of the function //
At this line: m_addr.sin_addr.s_addr
I get zero.
You should first resolve the IP address of your Domain name from DNS server then try to establish the connection .
gethostbyname will give the list of IP address which resolved from the Domain name with the hostent structure . you can use it as follow :
struct hostent *hent;
hent = gethostbyname(host.c_str());
Then move over the list of address hostent give you and test the connection,here is the hostent structure and gethostbyname definition :
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}