Related
i wrote an script, who can create an connection to an HTTP Server and shows the content of the website in the console.
Very easy.
But i want to connect to an https server and do the same procedures.
I searched at google and didn't found what i searched.
Please help me and give me an tutorial who can i use the openssl library.
I tried myself on the openssl library, but the library is very complicated and difficult to understand.
Here is my code of the http client:
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>
#include <arpa/inet.h>
#include <openssl/ssl.h>
using namespace std;
int sock;
struct sockaddr_in client;
int PORT = 80;
int main(int argc, char const *argv[])
{
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
client.sin_addr.s_addr = inet_addr("172.16.0.6");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
cout << "Error creating socket." << endl;
exit(1);
}
if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
close(sock);
cout << "Could not connect" << endl;
exit(1);
}
stringstream ss;
ss << "GET /" << "\r\n"
<< "Host: 172.16.1.4\r\n"
<< "Accept: application/json\r\n"
<< "Connection: close"
<< "\r\n\r\n";
string request = ss.str();
if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) {
cout << "Error sending request." << endl;
exit(1);
}
char cur;
while ( read(sock, &cur, 1) > 0 ) {
cout << cur;
}
return 0;
}
Here is a sample SSL client that connects to https://about.google/intl/en/ and prints downloaded a page : SSLClient.cpp
//============================================================================
// Name : SSLClient.cpp
// Compiling : g++ -c -o SSLClient.o SSLClient.cpp
// g++ -o SSLClient SSLClient.o -lssl -lcrypto
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <string.h>
using namespace std;
SSL *ssl;
int sock;
int RecvPacket()
{
int len=100;
char buf[1000000];
do {
len=SSL_read(ssl, buf, 100);
buf[len]=0;
printf("%s\n",buf);
// fprintf(fp, "%s",buf);
} while (len > 0);
if (len < 0) {
int err = SSL_get_error(ssl, len);
if (err == SSL_ERROR_WANT_READ)
return 0;
if (err == SSL_ERROR_WANT_WRITE)
return 0;
if (err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL)
return -1;
}
}
int SendPacket(const char *buf)
{
int len = SSL_write(ssl, buf, strlen(buf));
if (len < 0) {
int err = SSL_get_error(ssl, len);
switch (err) {
case SSL_ERROR_WANT_WRITE:
return 0;
case SSL_ERROR_WANT_READ:
return 0;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
default:
return -1;
}
}
}
void log_ssl()
{
int err;
while (err = ERR_get_error()) {
char *str = ERR_error_string(err, 0);
if (!str)
return;
printf(str);
printf("\n");
fflush(stdout);
}
}
int main(int argc, char *argv[])
{
int s;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
printf("Error creating socket.\n");
return -1;
}
struct sockaddr_in sa;
memset (&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("173.194.222.139"); // address of google.ru
sa.sin_port = htons (443);
socklen_t socklen = sizeof(sa);
if (connect(s, (struct sockaddr *)&sa, socklen)) {
printf("Error connecting to server.\n");
return -1;
}
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
const SSL_METHOD *meth = TLSv1_2_client_method();
SSL_CTX *ctx = SSL_CTX_new (meth);
ssl = SSL_new (ctx);
if (!ssl) {
printf("Error creating SSL.\n");
log_ssl();
return -1;
}
sock = SSL_get_fd(ssl);
SSL_set_fd(ssl, s);
int err = SSL_connect(ssl);
if (err <= 0) {
printf("Error creating SSL connection. err=%x\n", err);
log_ssl();
fflush(stdout);
return -1;
}
printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
char *request = "GET https://about.google/intl/en/ HTTP/1.1\r\n\r\n";
SendPacket(request);
RecvPacket();
return 0;
}
Note that if you want to exchange data between client and server with openssl, you might need to process error codes SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE as described in documentation. But it's not necessary here as HTTPS protocol is serial.
I'm trying to implement bluetooth piconet using C programming language. I have read some papers and also gone through some examples. But i didn't get proper output. I designed server and client using following example, please check this link. Please check out the code i'm working on:
Can anyone please suggest a proper method to implement it. Thank you.
slave.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <unistd.h>
void send_message_function(char[]);
void receive_ack();
int main()
{
int i;
pthread_t thread1, thread2;
char dest1[18] = "00:1B:10:00:2A:EC";
send_message_function(dest1);
}
void send_message_function(char ptr[18])
{
//printf("MAC::%s",ptr);
struct sockaddr_l2 addr = { 0 };
int s, stat, status, i;
char dest[18], buf[1024];
int bytes_read;
strncpy(dest, ptr, 18);
// allocate a socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// set the connection parameters (who to connect to)
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(0x1001);
str2ba(dest, &addr.l2_bdaddr);
status = connect(s, (struct sockaddr *) &addr, sizeof(addr));
if (status == 0) {
stat = write(s, "hello!", 6);
bytes_read = read(s, buf, sizeof(buf));
if (bytes_read > 0) {
printf("received %s\n", buf);
bzero(buf, 16);
}
}
if (status < 0)
perror("uh oh");
close(s);
}
master.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
void send_ack(char[]);
int main(int argc, char **argv) {
struct sockaddr_l2 loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read,status;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
// bind socket to port 0x1001 of the first available
// bluetooth adapter
loc_addr.l2_family = AF_BLUETOOTH;
loc_addr.l2_bdaddr = *BDADDR_ANY;
loc_addr.l2_psm = htobs(0x1001);
bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
while(1){
client = accept(s, (struct sockaddr *) &rem_addr, &opt);
memset(buf, 0, sizeof(buf));
// accept one connection
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if (bytes_read > 0) {
printf("received [%s]\n", buf);
status = write(client, "acknowledgement!", 16);
}
//ba2str(&rem_addr.l2_bdaddr, buf);
//send_ack(buf);
}
close(client);
close(s);
}
this is client server application I want to establish SIP (session initiation protocol) between client and server.
So please anyone guide me how can I do this.
server.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <netinet/tcp.h>
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
#define MAXDATASIZE 100
void str_server(int);
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(void)
{
int sockfd, numbytes,new_fd, optlen; // listen on sock_fd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
struct tcp_info info;
socklen_t sin_size;
struct sigaction sa;
char buf[MAXDATASIZE];
int yes=1;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
while(1) { // main accept() loop
sin_size = sizeof their_addr;
getchar();
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \
&sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n", \
inet_ntoa(their_addr.sin_addr));
if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
if ((numbytes=recv(new_fd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received From Client: %s\n",buf);
str_server(sockfd);
FILE *fp = fopen( "adventure.mpg", "rb" );
//if(!fork())
// execlp("gedit", "gedit", "SIPFILE.txt", NULL);
//system("popen /home/umair/Documents/CurrentData/SIPFILE.txt");
//ShellExecute(GetDesktopWindow(), "open","ls /home/umair/Documents
/CurrentData/SIPFILE.txt",NULL, NULL, SW_SHOW);
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd); // parent doesn't need this
}
return 0;
}
void str_server(int sock)
{
char buf[1025];
const char* filename = "test.text";
FILE *file = fopen(filename, "rb");
if (!file)
{
printf("Can't open file for reading");
return;
}
while (!feof(file))
{
int rval = fread(buf, 1, sizeof(buf), file);
if (rval < 1)
{
printf("Can't read from file");
fclose(file);
return;
}
int off = 0;
do
{
int sent = send(sock, &buf[off], rval - off, 0);
if (sent < 1)
{
// if the socket is non-blocking, then check
// the socket error for WSAEWOULDBLOCK/EAGAIN
// (depending on platform) and if true then
// use select() to wait for a small period of
// time to see if the socket becomes writable
// again before failing the transfer...
printf("Can't write to socket");
fclose(file);
return;
}
off += sent;
}
while (off < rval);
}
fclose(file);
}
//client.c :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#define PORT 3490 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
void RecvFile(int , const char* );
FILE *filename;
int main(int argc, char *argv[])
{
int sockfd, numbytes, optlen;
char buf[MAXDATASIZE];
char *message;
struct hostent *he;
struct tcp_info info;
struct sockaddr_in their_addr; // connector's address information
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
if (connect(sockfd, (struct sockaddr *)&their_addr,
sizeof their_addr) == -1) {
perror("connect");
exit(1);
}
printf("connect successfull\n");
/* if (send(sockfd, "Hello, world!\n", 14, 0) == -1)
perror("send");
printf("send successfull\n");
*/
message = "GET /?st=1 HTTP/1.1\r\nHost: www.msn.com\r\n\r\n";
if( send(sockfd , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
RecvFile(sockfd , message);
optlen = sizeof(info);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received: %s\n",buf);
close(sockfd);
return 0;
}
void RecvFile(int sock, const char* filename)
{
int rval;
char buf[0x1000];
FILE *file = fopen(filename, "wb");
if (!file)
{
printf("Can't open file for writing");
return;
}
do
{
rval = recv(sock, buf, sizeof(buf), 0);
if (rval < 0)
{
// if the socket is non-blocking, then check
// the socket error for WSAEWOULDBLOCK/EAGAIN
// (depending on platform) and if true then
// use select() to wait for a small period of
// time to see if the socket becomes readable
// again before failing the transfer...
printf("Can't read from socket");
fclose(file);
return;
}
if (rval == 0)
break;
int off = 0;
do
{
int written = fwrite(&buf[off], 1, rval - off, file);
if (written < 1)
{
printf("Can't write to file");
fclose(file);
return;
}
off += written;
}
while (off < rval);
}
while (!feof(file));
fclose(file);
}
Any Suggestion?
I am not sure what you are trying to do with SIP, but the code snippet you've provided shows only establishing a TCP/IP connection. If you intend to do a SIP server-client application, I suggest that you look for a library to help you along the way.
One that I know of that is very complete is called Sofia SIP:
http://sofia-sip.sourceforge.net/
It's written by Nokia for Linux in C language.
Source code is available here: http://gitorious.org/sofia-sip/sofia-sip/trees/master
(Older http://sourceforge.net/p/sofia-sip/git/ci/master/tree/)
you can learn about sipp scenarios and message passing through this utility and its documentation.
I am trying to implement Socket where client send sentence to server and server replies back two integer valeus pcount and ncount. I can receive both this but first recv operation receives both values and also appends some other data to buffer.
Client.cpp
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
char *foo(char* buf)
{
char buffer[1024];
char *a='\0';
char *c=buf;
strcpy(buffer,buf);
int host_port= 1102;
char* host_name="127.0.0.1";
struct sockaddr_in my_addr;
//char buffer[1024];
int bytecount;
int buffer_len=0;
int hsock;
int * p_int;
int err;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error initializing socket %d\n",errno);
goto FINISH;
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n",errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = inet_addr(host_name);
if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
if((err = errno) != EINPROGRESS){
fprintf(stderr, "Error connecting socket %d\n", errno);
goto FINISH;
}
}
//Now lets do the client related stuff
buffer_len = 1024;
memset(buf, '\0', buffer_len);
buf[strlen(buf)-1]='\0';
if( (bytecount=send(hsock, buffer, strlen(buffer),0))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
go
to FINISH;
}
printf("Sent bytes %d\n", bytecount);
//-------
// may Needs to empty content of buffer here but dont know how to do. Tried with fflush, free(buffer) but does not work
//Two recv function which ideally recv pcount and ncount subsequently
if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
goto FINISH;
}
printf("Recieved bytes %d\nReceived string \"%s \n", bytecount, buffer);
//Needs to empty content of buffer here but dont know how to do. Tried with fflush, free(buffer) but does not work
if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
goto FINISH;
}
printf("Recieved bytes %d\nReceived string \"%s \n", bytecount, buffer);
close(hsock);
FINISH:
;
return buffer;
}
And server.cpp :
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
//#include <errno.h>
#include <stdio.h>
#include <netinet/in.h>
#include <resolv.h>
#include <sys/socket.h>
#include <unistd.h>
//#include <sstream.h>
#include <pthread.h>
#include "serverFunction.cpp"
#include "serverFunction2.cpp"
#include <iostream>
#include <sstream>
#include <cstdio>
using namespace std;
void *SocketHandler(void *);
int main(int argv, char **argc)
{
int host_port = 1102;
char buf[20];
int k;
struct sockaddr_in my_addr;
int hsock;
int *p_int;
int err;
socklen_t addr_size = 0;
int *csock;
sockaddr_in sadr;
pthread_t thread_id = 0;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if (hsock == -1) {
printf("Error initializing socket %dn", errno);
goto FINISH;
}
p_int = (int *) malloc(sizeof(int));
*p_int = 1;
if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
printf("Error setting options %dn", errno);
free(p_int);
goto FINISH;
}
free(p_int);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
goto FINISH;
}
if (listen(hsock, 10) == -1) {
fprintf(stderr, "Error listening %dn", errno);
goto FINISH;
}
//Now lets do the server stuff
addr_size = sizeof(sockaddr_in);
while (true) {
printf("waiting for a connectionn\n");
csock = (int *) malloc(sizeof(int));
if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
pthread_detach(thread_id);
} else {
fprintf(stderr, "Error accepting %dn", errno);
}
}
FINISH:
;
}
void *SocketHandler(void *lp)
{
int result=0;
//std::stringstream ss;
int *csock = (int *) lp;
char buf[20];
int k;
// char *target="my name is khan";
char *str;
char *str2;
int pcount = 0, ncount = 0;
char buffer[1024];
int buffer_len = 1024;
int bytecount;
int i = 0,t=0,q=0;
int j = 0;
char *ch[50] = { 0 }; /* stores references to 50 words. */
char *ch2[50] = { 0 };
char *word = strtok(buffer, " ");
char *word2 = strtok(buffer, " ");
char *portstring1=(char *)malloc(sizeof(buffer));
char *portstring2=(char *)malloc(sizeof(buffer));
memset(buffer, 0, buffer_len);
if ((bytecount = recv(*csock, buffer, buffer_len, 0)) == -1) {
fprintf(stderr, "Error receiving data %d \n", errno);
goto FINISH;
}
printf("Received bytes %d \n Received string %s \n ", bytecount, buffer);
/* stores references to 50 words. */
word = strtok(buffer, " ");
while ((NULL != word) && (50 > i)) {
ch[i] = strdup(word);
//printf("%s n", ch[i]);
str = BoyerMoore_positive(ch[i], strlen(ch[i]) - 1);
str2= BoyerMoore_negative(ch[i], strlen(ch[i]) - 1);
if (str == NULL)
t++;
else {
printf("%s \n", ch[i]);
// puts("true");
pcount += 1;
printf("Positive count is: %d \n",pcount);
}
if(str2== NULL)
q++;
else {
printf("%s \n", ch[i]);
// puts("true");
ncount += 1;
printf("Nagative count is: %d \n",ncount);
}
i++;
word = strtok(NULL, " ");
}
//I want to send pcount and ncount values to client
**sprintf(portstring1, "%d", pcount);
if ((bytecount = send(*csock, portstring1, 1, 0)) == -1) {
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}
sprintf(portstring2, "%d", ncount);
if ((bytecount = send(*csock, portstring2, strlen(portstring2), 0)) == -1) {
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}**
FINISH:
free(csock);
return 0;
}
I receive output like this:
Enter sentence to send to the server (press enter)
critic worst nice
Sent bytes 18
Recieved bytes 2
Received string 12itic worst nice //Here there should be only 1 2. Why 'itic ..' gets appended. And why 1 and 2 both does not get printed one after another
You forgot to design and implement a protocol. Network communication doesn't work by magic. If you have a notion of an application-level message, you have to write code to send and receive application-level messages. You haven't done this, so of course it won't happen.
Also:
printf("Received bytes %d \n Received string %s \n ", bytecount, buffer);
The %s format specifier is only for C-style strings. It's not suitable for arbitrary data. How would it know how many bytes to print?
The recv function does not add a nul character to terminate the received string. You have to add it yourself, like this:
if((bytecount = recv(hsock, buffer, buffer_len-1, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
goto FINISH;
}
buffer[bytecount]=0;
Notice the -1 in buffer len, to make sure there's room for the nul character.
#Joni and David- Thanks for your support!
Problem solved:
at sender:
int ar[2];
if ((bytecount = send(*csock, (char *)ar, 2 *sizeof(int), 0)) == -1) { // Here we cant send lenth-1. It consider exact
fprintf(stderr, "Error sending data %d\n", errno);
goto FINISH;
}
at receiver side:
if((bytecount = recv(hsock, ar, 2 * sizeof(int), 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
goto FINISH;
}
for(k=0;k<2;k++)
{
printf("count is :%d",ar[k]);
}
just took and array, Now I can send any receive any numbers of values! It's so easy!
I have a C++ program using the Berkley sockets API on Linux. I have one end of the connection sending two IP addresses to the client. I can represent these using inet_ntop() and inet_pton(), but this would make the message length 2*INET6_ADDRSTRLEN, which is 92 bytes. That seems a little much for two IP addresses. Is there a portable, compact binary representation of IP addresses (it must work with both IPv4 and IPv6).
If you have an addrinfo lying around, then send the .ai_addr and .ai_addrlen.
Try these two programs:
send_sockaddr.cc:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
int main (int ac, char **av) {
if(ac != 3) {
fprintf(stderr, "Usage: %s hostname portnumber\n", *av);
return 1;
}
struct addrinfo *res0;
struct addrinfo hints = { AI_CANONNAME, 0, SOCK_DGRAM };
int rc = getaddrinfo(av[1], av[2], &hints, &res0);
if(rc) {
fprintf(stderr, "%s/%s: %s\n", av[1], av[2], gai_strerror(rc));
return 1;
}
char *name = res0->ai_canonname;
for(struct addrinfo *res = res0; res; res=res->ai_next) {
fprintf(stderr, "%s: %04X/%04X/%04X ", name, res->ai_family, res->ai_socktype, res->ai_protocol);
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0) {
perror("socket");
continue;
}
rc = connect(fd, res->ai_addr, res->ai_addrlen);
if(rc < 0) {
perror("connect");
continue;
}
fprintf(stderr, "Connected (%d)\n", fd);
*(unsigned short*)res->ai_addr = htons(*(unsigned short*)res->ai_addr);
rc = send(fd, res->ai_addr, res->ai_addrlen, 0);
*(unsigned short*)res->ai_addr = ntohs(*(unsigned short*)res->ai_addr);
if(rc < 0) {
perror("send");
}
close(fd);
}
freeaddrinfo(res0);
}
listen_sockaddr.cc:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <poll.h>
#include <vector>
#include <arpa/inet.h>
int main (int ac, char **av) {
if(ac != 2) {
fprintf(stderr, "Usage: %s portnumber\n", *av);
return 1;
}
struct addrinfo *res0;
struct addrinfo hints = { 0, 0, SOCK_DGRAM };
int rc = getaddrinfo(0, av[1], &hints, &res0);
if(rc) {
fprintf(stderr, "%s/%s: %s\n", av[1], av[2], gai_strerror(rc));
return 1;
}
char *name = res0->ai_canonname;
std::vector<pollfd> fds;
for(struct addrinfo *res = res0; res; res=res->ai_next) {
fprintf(stderr, "%s: ", name);
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0) {
perror("socket");
continue;
}
rc = bind(fd, res->ai_addr, res->ai_addrlen);
if(rc < 0) {
perror("bind");
continue;
}
fprintf(stderr, "Bound (%d)\n", fd);
fds.push_back(pollfd({fd, POLLIN}));
}
freeaddrinfo(res0);
while( (rc = poll( &fds[0], fds.size(), -1)) > 0 ) {
for(size_t i = 0; i < fds.size(); ++i) {
pollfd& pfd = fds[i];
if(!pfd.revents)
continue;
pfd.revents = 0;
union {
sockaddr s;
sockaddr_in sin;
sockaddr_in6 sin6;
} u;
rc = recv(pfd.fd, &u, sizeof u, 0);
if(rc < 0) {
perror("recv");
continue;
}
fprintf(stderr, "Received %d bytes\n", rc);
char str[256];
switch(ntohs(u.s.sa_family)) {
case AF_INET:
if(inet_ntop(AF_INET, &u.sin.sin_addr, str, sizeof str)) {
fprintf(stderr, "AF_INET %s\n", str);
} else {
fprintf(stderr, "AF_INET unknown\n");
}
break;
case AF_INET6:
if(inet_ntop(AF_INET6, &u.sin6.sin6_addr, str, sizeof str)) {
fprintf(stderr, "AF_INET6 %s\n", str);
} else {
fprintf(stderr, "AF_INET6 unknown\n");
}
break;
default:
fprintf(stderr, "UNKNOWN\n");
break;
}
}
}
}
Actually, IP addresses aren't numbers itself, so the byte representation would always follow Big-Endian. At least I don't know any platform where this is different. It's just not handled as a number, but as 4 bytes.