/*********************************************************************************
|
* Copyright: (C) 2018 LingYun I.o.T Studio <www.iot-yun.com>
|
* All rights reserved.
|
*
|
* Filename: socket_client.c
|
* Description: This is a sample socket client demo program.
|
* Usage: socket_client -i 192.168.2.18 -p 6666
|
*
|
* Version: 1.0.0(06/08/2012~)
|
* Author: Guo Wenxue <guowenxue@gmail.com>
|
* ChangeLog: 1, Release initial version on "06/08/2012 02:50:51 PM"
|
*
|
********************************************************************************/
|
|
/* Some Unix Program Standard head file */
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <string.h>
|
#include <getopt.h> /* getopt_long */
|
#include <libgen.h> /* getopt_long */
|
|
/* Socket Program head file */
|
#include <sys/types.h>
|
#include <sys/socket.h>
|
#include <netinet/in.h> /* sockaddr_in{} and other Internet define */
|
|
#include <errno.h> /* strerror(), perror(), errno head file*/
|
#include <arpa/inet.h> /* For inet_pton() */
|
|
#define MAX_BUF_SIZE 1024
|
|
#define LOGON_INFO "lingyun:www.iot-yun.com"
|
|
#define MAJOR 1
|
#define MINOR 0
|
#define REVER 0
|
|
void print_version(char *progname)
|
{
|
printf("%s Version 1.0.0\n", progname);
|
printf("Copyright (C) 2012 Guo Wenxue<guowenxue@gmail.com>.\n");
|
return;
|
}
|
|
void print_usage(char *progname)
|
{
|
print_version(progname);
|
|
printf("Usage: %s [OPTION]...\n", progname);
|
printf(" %s is a socket client test program, which used to logon server and send string to server\n", progname);
|
|
printf("\nMandatory arguments to long options are mandatory for short options too:\n");
|
|
printf(" -i[ipaddr ] Socket server IP address\n");
|
printf(" -p[port ] Socket server port address\n");
|
printf(" -h[help ] Display this help information\n");
|
printf(" -v[version ] Display the program version\n");
|
|
printf("\nExample: %s -i 192.168.2.18 -p 8900\n", progname);
|
return ;
|
}
|
|
|
/* Argc is the program linux running command arguments count, and argv is
|
* the arguments string value. All of the arguments take as string.
|
*/
|
int main(int argc, char **argv)
|
{
|
int sockfd, len, rv;
|
int opt;
|
char *progname = NULL;
|
char *server_ip = NULL;
|
unsigned short server_port = 0;
|
char buf[MAX_BUF_SIZE];
|
struct sockaddr_in servaddr;
|
|
struct option long_options[] =
|
{
|
{"ipaddr", required_argument, NULL, 'i'},
|
{"port", required_argument, NULL, 'p'},
|
{"version", no_argument, NULL, 'v'},
|
{"help", no_argument, NULL, 'h'},
|
{NULL, 0, NULL, 0}
|
};
|
|
progname = basename(argv[0]);
|
|
/* Parser the command line parameters */
|
while ((opt = getopt_long(argc, argv, "i:p:vh", long_options, NULL)) != -1)
|
{
|
switch (opt)
|
{
|
case 'p':
|
server_port = atoi(optarg);
|
break;
|
|
case 'i':
|
server_ip = optarg;
|
break;
|
|
case 'v':
|
print_version(progname); /* Defined in version.h */
|
return EXIT_SUCCESS;
|
|
case 'h': /* Get help information */
|
print_usage(progname);
|
return EXIT_SUCCESS;
|
|
default:
|
break;
|
}
|
}
|
|
if(NULL==server_ip || 0==server_port)
|
{
|
print_usage(progname);
|
return -1;
|
}
|
|
/* Open an IPV4(AF_INET) TCP(SOCK_STREAM) Socket File Description, UDP socket should
|
* use SOCK_DGRAM,We can use linux command "man socket" to see this function manual
|
*/
|
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
{
|
/* strerror() is the 1st way to display the failure reason, argument
|
* errno is a globle variable defined in <errno.h>, we can use linux command
|
* "man strerror" to see this function manual*/
|
printf("Use socket() to create a TCP socket failure: %s\n", strerror(errno));
|
return -1;
|
}
|
|
/* Now we set the Server Information, include IPV4 or IPV6, Server Port, Server IP address */
|
memset(&servaddr, 0, sizeof(servaddr));
|
servaddr.sin_family = AF_INET; /* Set it as IPV4 protocal */
|
servaddr.sin_port = htons(server_port); /*Server port*/
|
|
/* argv[1] we take as Server IP address, it's the second arguments in running command */
|
if (inet_pton(AF_INET, server_ip, &servaddr.sin_addr) <= 0)
|
{
|
printf("Use inet_pton() to set the Server IP address failure.\n");
|
rv = -2;
|
goto CleanUp;
|
}
|
|
/* Now call connect() function to connect to the server, we can use linux command "man connect"
|
* to see this function manual */
|
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
|
{
|
printf("Connect to the server [%s:%d] failure: %s\n", server_ip, server_port, strerror(errno));
|
rv = -3;
|
goto CleanUp;
|
}
|
printf("Connect to Server [%s:%d] ok\n", server_ip, server_port);
|
|
#ifdef CONFIG_VERIFY_USER
|
if( write(sockfd, LOGON_INFO, strlen(LOGON_INFO)) < 0)
|
{
|
printf("Write logon information to server failure: %s\n", strerror(errno));
|
goto CleanUp;
|
}
|
|
/* Once we connect to the server successfully, we can receive the data from the socket socekt */
|
memset(buf, 0, sizeof(buf));
|
if( (len = read(sockfd, buf, MAX_BUF_SIZE)) < 0)
|
{
|
printf("socket read data from server[%s] failure:%s\n", server_ip, strerror(errno));
|
goto CleanUp;
|
}
|
else if( 0 == len )
|
{
|
printf("logon to server[%s] failure and socket disconnected\n", server_ip);
|
goto CleanUp;
|
}
|
|
/* socket read data from server */
|
if( strncasecmp(buf, "passed", 6) )
|
{
|
printf("Logon to server[%s] failure: %s\n", server_ip, buf);
|
goto CleanUp;
|
}
|
printf("Logon to server successfully!\n");
|
#endif
|
|
while(1)
|
{
|
printf("\nplease input string to send to server:\n==> ");
|
|
memset(buf, 0, sizeof(buf));
|
fgets(buf, sizeof(buf), stdin);
|
write(sockfd, buf, strlen(buf));
|
|
memset(buf, 0, sizeof(buf));
|
rv=read(sockfd, buf, sizeof(buf));
|
if(rv <= 0)
|
{
|
printf("ERROR:socket disconnected or get error\n");
|
goto CleanUp;
|
}
|
|
printf("<== %s\n", buf);
|
}
|
|
|
CleanUp:
|
close(sockfd); /* We must close socket File Description when program exit*/
|
return 0;
|
}
|