7. Глава V. Примерни програми за ползване на ЗЗЗ сървър от различни програмни езици

Навсякъде в примерите се използва име на хост “localhost” и номер на порт “3333”. Това са стойностите по подразбиране, но те могат да са различни в зависимост от вашата инсталация.

7.1 Примерна програма на C

zzzclient.h:
/*
 * zzzclient.h
 *
 * Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */

#ifndef __ZZZCLIENT_H__
#define __ZZZCLIENT_H__

#include <conio.h>	// getch
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#define socklen_t int
#else
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdint.h>
#include <fcntl.h>

#define closesocket close
#if !defined(O_BINARY)
#define O_BINARY 0
#endif
#endif

int zzzclient_init_socket();
void zzzclient_uninit_socket();
void zzzclient_init(int* sock);
void zzzclient_destroy(int* sock);
BOOL zzzclient_connect(int* sock, char* host, int port);
void zzzclient_close(int* sock);
BOOL zzzclient_send(int* sock, char* data);
char* zzzclient_receive(int* sock, char* result);
char* zzzclient_zzzprogram(char* host, int port, char* data, char* result);

#endif // __ZZZCLIENT_H__
zzzclient.c:
/*
 * zzzclient.c
 *
 * Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */ 

#include "zzzclient.h"


int zzzclient_init_socket()
{
#ifdef WIN32
	WSADATA wsaData;
	if (
		WSAStartup(MAKEWORD(2, 2), &wsaData) &&
		WSAStartup(MAKEWORD(2, 1), &wsaData) &&
		WSAStartup(MAKEWORD(1, 1), &wsaData)
		)
	{
		return 0;
	}
#endif
	return 1;
}

void zzzclient_uninit_socket()
{
#ifdef WIN32
	WSACleanup();
#endif
}

void zzzclient_init(int* sock)
{
    *sock = -1;

	zzzclient_init_socket();
}

void zzzclient_destroy(int* sock)
{
	zzzclient_close(sock);

	zzzclient_uninit_socket();
}

/**
    Connect to a host on a certain port number
*/
BOOL zzzclient_connect(int* sock, char* address , int port)
{
    struct sockaddr_in server;

    // create socket if it is not already created
    if(*sock == -1)
    {
        //Create socket
        *sock = (int)socket(AF_INET , SOCK_STREAM , 0);
        if (*sock == -1)
        {
            // Could not create socket
        }

        // Socket created
    }
    else    {   /* OK , nothing */  }

    // setup address structure
    if((int)inet_addr(address) == -1)
    {
        struct hostent *he;
        struct in_addr **addr_list;

        // resolve the hostname, its not an ip address
        if((he = gethostbyname(address)) == NULL)
        {
            // Failed to resolve hostname

            return FALSE;
        }

        // Cast the h_addr_list to in_addr , since h_addr_list also has the \
ip address in long format only
        addr_list = (struct in_addr **) he->h_addr_list;

        server.sin_addr = *addr_list[0];
    }
    // plain ip address
    else
    {
        server.sin_addr.s_addr = inet_addr(address);
    }

    server.sin_family = AF_INET;
    server.sin_port = htons( port );

    // Connect to remote server
    if (connect(*sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        // Error: Connect failed.
        return 1;
    }

#ifndef _WIN32
    {
		int sockFlags;
		sockFlags = fcntl(sock, F_GETFL, 0);
		sockFlags |= O_NONBLOCK;
		fcntl(sock, F_SETFL, sockFlags);
    }
#endif

    // Connected
    return TRUE;
}

/**
    Send data to the connected host
*/
BOOL zzzclient_send(int* sock, char* data)
{
    // Send some data
    if(send(*sock, data, (int)strlen(data)+1, 0) < 0)
    {
        // Send failed
        return FALSE;
    }
    // Data "data" send;

    return TRUE;
}

/**
    Receive data from the connected host
*/
char* zzzclient_receive(int* sock, char* result)
{
	char buffer[512];
	int len = 0;
	int all=0;
    result[0] = '\0';

	if(result == NULL)
		return result;

    // Receive a reply from the server
    while((len = (int)recv(*sock , buffer , sizeof(buffer) , 0)) > 0)
    {
		buffer[len] = '\0';
		memcpy(&result[all], buffer, len);
	    all += len;
    }

    return result;
}

void zzzclient_close(int* sock)
{
	if(sock >= 0)
	{
		closesocket(*sock);
		*sock = -1;
	}
}

char* zzzclient_zzzprogram(char* host, int port, char* data, char* result)
{
	int sock;

	if(result == NULL)
		return result;

	zzzclient_init(&sock);

	if(zzzclient_connect(&sock, host, port))
	{
		zzzclient_send(&sock, data);
		result = zzzclient_receive(&sock, result);
		zzzclient_close(&sock);
	}

	zzzclient_destroy(&sock);

	return result;
}
main.c:
// main.c : Defines the entry point for the console application.
//

#include "zzzclient.h"
#include <stdio.h>


int main(int argc, char* argv[])
{
	char ch;
	char result[1024] = "";

	zzzclient_zzzprogram("localhost", 3333, "#[cout;Hello World from ZZZServer!\
]", result);

	printf("%s\n", result);

	printf("%s", "Press any key...");


#ifdef _WIN32
	ch = _getch();
#else
	ch = getch();
#endif

	return 0;
}

7.2 Примерна програма на C++

ZZZClient.h:
/*
 * ZZZClient.h
 *
 * Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */

#ifndef __ZZZCLIENT_H__
#define __ZZZCLIENT_H__

#include <iostream>	// cout
#include <string>	// string
#include <conio.h>	// getch
#ifdef _WIN32
#include <windows.h>
#include <io.h>
#define socklen_t int
#else
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdint.h>
#include <fcntl.h>

#define closesocket close
#if !defined(O_BINARY)
#define O_BINARY 0
#endif
#endif

using namespace std;

class ZZZClient
{
private:
    int sock;
    struct sockaddr_in server;
	int InitSocket();
	void UninitSocket();

public:
    ZZZClient();
	virtual ~ZZZClient();
    BOOL Connect(string, int);
	void Close();
    BOOL Send(string data);
    string Receive();
	string ZZZProgram(string host, int port, string data);
};

#endif // __ZZZCLIENT_H__
ZZZClient.cpp:
/*
 * ZZZClient.cpp
 *
 * Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */ 

#include "ZZZClient.h"


int ZZZClient::InitSocket()
{
#ifdef WIN32
	WSADATA wsaData;
	if (
		WSAStartup(MAKEWORD(2, 2), &wsaData) &&
		WSAStartup(MAKEWORD(2, 1), &wsaData) &&
		WSAStartup(MAKEWORD(1, 1), &wsaData)
		)
	{
		return 0;
	}
#endif
	return 1;
}

void ZZZClient::UninitSocket()
{
#ifdef WIN32
	WSACleanup();
#endif
}

ZZZClient::ZZZClient()
{
    this->sock = -1;

	InitSocket();
}

ZZZClient::~ZZZClient()
{
	Close();

	UninitSocket();
}

/**
    Connect to a host on a certain port number
*/
BOOL ZZZClient::Connect(string address , int port)
{
    // create socket if it is not already created
    if(sock == -1)
    {
        //Create socket
        sock = (int)socket(AF_INET , SOCK_STREAM , 0);
        if (sock == -1)
        {
            // Could not create socket
        }

        // Socket created
    }
    else    {   /* OK , nothing */  }

    // setup address structure
    if((int)inet_addr(address.c_str()) == -1)
    {
        struct hostent *he;
        struct in_addr **addr_list;

        // resolve the hostname, its not an ip address
        if ( (he = gethostbyname( address.c_str() ) ) == NULL)
        {
            // Failed to resolve hostname

            return FALSE;
        }

        // Cast the h_addr_list to in_addr , since h_addr_list also has the \
ip address in long format only
        addr_list = (struct in_addr **) he->h_addr_list;

        server.sin_addr = *addr_list[0];
    }
    // plain ip address
    else
    {
        server.sin_addr.s_addr = inet_addr( address.c_str() );
    }

    server.sin_family = AF_INET;
    server.sin_port = htons( port );

    // Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        // Error: Connect failed.
        return 1;
    }

#ifndef _WIN32
    {
		int sockFlags;
		sockFlags = fcntl(sock, F_GETFL, 0);
		sockFlags |= O_NONBLOCK;
		fcntl(sock, F_SETFL, sockFlags);
    }
#endif

    // Connected
    return TRUE;
}

/**
    Send data to the connected host
*/
BOOL ZZZClient::Send(string data)
{
    // Send some data
    if( send(sock , data.c_str() , (int)strlen(data.c_str())+1 , 0) < 0)
    {
        // Send failed
        return FALSE;
    }
    // Data "data" send;

    return TRUE;
}

/**
    Receive data from the connected host
*/
string ZZZClient::Receive()
{
	char buffer[512];
    string reply = "";

    // Receive a reply from the server
	int len = 0;
    while((len = (int)recv(sock , buffer , sizeof(buffer) , 0)) > 0)
    {
		buffer[len] = '\0';
	    reply += buffer;
    }

    return reply;
}

void ZZZClient::Close()
{
	if(this->sock >= 0)
	{
		closesocket(this->sock);
		this->sock = -1;
	}
}

string ZZZClient::ZZZProgram(string host, int port, string data)
{
	string result;

	if(Connect(host, port))
	{
		Send(data);
		result = Receive();
		Close();
	}
	return result;
}
main.cpp:
/*
 * main.cpp
 *
 * Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */

#include "ZZZClient.h"

int main(int argc, char* argv[])
{
	ZZZClient client;

	cout << client.ZZZProgram("localhost", 3333, "#[cout;Hello World from ZZZSe\
rver!]") << endl;

	cout << "Press any key...";

#ifdef _WIN32
	char ch = _getch();
#else
	char ch = getch();
#endif

	return 0;
}

7.3 Примерна програма на C#

Hello world from ZZZServer:
/*
 * Copyright (C) 2013-2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */

using System;
using System.Net.Sockets;
using System.Text;

namespace ZZZClientCS
{
    class Program
    {
        static string ZZZProgram(string serverHost, int serverPort, string p\
rogram)
        {
            try
            {
                if (serverHost.Equals("localhost"))
                    serverHost = "127.0.0.1";
                TcpClient tc = new TcpClient(serverHost, serverPort);
                NetworkStream ns = tc.GetStream();

                if (ns.CanWrite && ns.CanRead)
                {
                    // Do a simple write.
                    byte[] sendBytes = Encoding.UTF8.GetBytes(program + '\0'\
);
                    ns.Write(sendBytes, 0, sendBytes.Length);

                    // Read the NetworkStream into a byte buffer.
                    byte[] bytes = new byte[tc.ReceiveBufferSize];

                    StringBuilder returndata = new StringBuilder();
                    int receivedBytes = ns.Read(bytes, 0, tc.ReceiveBufferSi\
ze);
                    returndata.Append(Encoding.UTF8.GetString(bytes, 0, rece\
ivedBytes));
                    while (receivedBytes > 0)
                    {
                        receivedBytes = ns.Read(bytes, 0, tc.ReceiveBufferSi\
ze);
                        returndata.Append(Encoding.UTF8.GetString(bytes, 0, \
receivedBytes));
                    }

                    // Return the data received from the host.
                    return returndata.ToString();
                }
                else
                {
                    if (!ns.CanRead)
                    {
                        Console.WriteLine("cannot not read data from this st\
ream");
                        tc.Close();
                    }
                    else
                    {
                        if (!ns.CanWrite)
                        {
                            Console.WriteLine("cannot write data to this str\
eam");
                            tc.Close();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            return String.Empty;
        }

        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;

            DateTime startTime = DateTime.UtcNow;

            Console.WriteLine(ZZZProgram("localhost", 3333, "#[cout;Hello Wo\
rld from ZZZServer!]"));

            DateTime stopTime = DateTime.UtcNow;
            long elapsedTime = stopTime.Millisecond - startTime.Millisecond;
            Console.WriteLine(elapsedTime.ToString() + " milliseconds");

            Console.ReadKey();
        }
    }
}

7.4 Примерна програма на Java

Hello world from ZZZServer:
/*
 * Copyright (C) 2013-2016 ZZZ Ltd. - Bulgaria. All rights reserved.
 */
package zzzclientj;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

/**
 *
 * @author ZZZ Ltd. - Bulgaria
 */
public class MainApp {

    public static String ZZZProgram(String serverHost, int serverPort,
            String program)
    {
        String result = "";
        
        try {
        	if(serverHost.equals("localhost"))
        		serverHost = "127.0.0.1";
            Socket socket = new Socket(serverHost, serverPort);
            PrintWriter out = new PrintWriter(new OutputStreamWriter(
                    socket.getOutputStream(), "UTF-8"), true);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream(), "UTF-8"));
            
            out.print(program + '\0');
            out.flush();
            
            StringBuilder sb = new StringBuilder();
            int DEFAULT_BUFFER_SIZE = 1000;
            char buf[] = new char[DEFAULT_BUFFER_SIZE];
            int n;
            while ((n = in.read(buf)) > 0) {
                sb.append(buf, 0, n);

                if(!in.ready())
                    break;
            }
            result = sb.toString();

            out.close();
            in.close();
            socket.close();
        } catch(Exception e) {
            e.printStackTrace();
        }    
        
        return result;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    	long startTime = System.currentTimeMillis();
    	
        System.out.println(ZZZProgram("localhost", 3333, "#[cout;Hello world\
 from ZZZServer!]"));
        
        long stopTime = System.currentTimeMillis();
        long elapsedTime = stopTime - startTime;
        System.out.println(elapsedTime + " milliseconds");
	}
}

7.5 Примерна програма на PHP

Hello world from ZZZServer:
<?php
//
// Copyright (C) 2013-2016 ZZZ Ltd. - Bulgaria. All rights reserved.
//
	class Socket
	{
		var $m_host  = "";
		var $m_port  = 0;
		var $m_sock;
		var $buf = "";

		function Socket($host, $port)
		{
			$this->m_host = $host;
			$this->m_port = $port;
		}

		function Connect()
		{
			$this->m_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
			return socket_connect($this->m_sock, gethostbyname($this->m_host), $this-\
>m_port);
		}

		function send($data)
		{
			if(socket_write($this->m_sock, $data) == false)
			{
				printf("** failed to send(%s) **\n");
				return;
			}
		}

		function read($length = 2048)
		{
			return socket_read($this->m_sock, $length);
		}

		function kill()
		{
			socket_close($this->m_sock);
		}

		function print($s)
		{
			$this->send($s);
		}

		function read()
		{
			$response = '';
			while($resp = socket_read($this->m_sock, 1024)) {
				if(!$resp)
					break;
				$response .= $resp;
			}
			return $response;
		}
	}

	$host = "localhost";
	$port = 3333;
	function ZZZProgram($program) {
		global $host;
		global $port;
		$result="";
		$Connection = new Socket($host, $port);
		if($Connection->Connect()){
			$Connection->print($program + '\0');
			$result = $Connection->read();

			$Connection->kill();
		}
		return $result;
	}
	echo ZZZProgram("#[cout;[Hello world from ZZZServer!]]");
?>

7.6 Примерна програма на Python

Hello world from ZZZServer:
#
# Copyright (C) 2016 ZZZ Ltd. - Bulgaria. All rights reserved.
#
import socket, sys
 
def zzzprogram(host, port, program) :
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.settimeout(2)
	 
	# connect to remote host
	try :
		s.connect((host, port))
	except :
		return
	 
	s.send((program + '\0').encode('utf-8'))

	result = ''
	while True :
		data = s.recv(4096)
		if not data :
			break
		result += data.decode('utf-8')
		
	s.close()
	return result
		
sys.stdout.write(
	zzzprogram('localhost', 3333,
		'#[cout;Hello World from ZZZServer!]'))

7.7 Примерна програма на VisualBasic

Hello world from ZZZServer:
'
' Copyright (C) 2013-2016 ZZZ Ltd. - Bulgaria. All rights reserved.
'

Imports System.Net.Sockets
Imports System.Text

Module ZZZClientVB

    Function ZZZProgram(ByVal serverHost As String, ByVal serverPort As Stri\
ng, ByVal program As String) As String
        Try
            If serverHost = "localhost" Then
                serverHost = "127.0.0.1"
            End If
            Dim tc As New TcpClient(serverHost, serverPort)
            Dim ns As NetworkStream = tc.GetStream()

            If ns.CanWrite And ns.CanRead Then
                ' Do a simple write.
                Dim sendBytes As [Byte]() = Encoding.UTF8.GetBytes(program &\
 Chr(0))
                ns.Write(sendBytes, 0, sendBytes.Length)

                ' Read the NetworkStream into a byte buffer.
                Dim bytes(tc.ReceiveBufferSize) As Byte
                Dim returndata As StringBuilder = New StringBuilder()
                Dim receivedBytes As Integer = ns.Read(bytes, 0, tc.ReceiveB\
ufferSize)
                returndata.Append(Encoding.UTF8.GetString(bytes, 0, received\
Bytes))
                While receivedBytes > 0
                    receivedBytes = ns.Read(bytes, 0, tc.ReceiveBufferSize)
                    returndata.Append(Encoding.UTF8.GetString(bytes, 0, rece\
ivedBytes))
                End While

                ' Return the data received from the host.
                Return returndata.ToString()
            Else
                If Not ns.CanRead Then
                    Console.WriteLine("cannot not read data from this stream\
")
                    tc.Close()
                Else
                    If Not ns.CanWrite Then
                        Console.WriteLine("cannot write data to this stream")
                        tc.Close()
                    End If
                End If
            End If
        Catch e As Exception
            Console.WriteLine(e)
        End Try

        Return ""
    End Function

    Sub Main()
        Console.OutputEncoding = Encoding.UTF8

        Dim startTime As DateTime = DateTime.UtcNow

        Console.WriteLine(ZZZProgram("localhost", 3333, "#[cout;Hello World \
from ZZZServer!]"))

        Dim stopTime As DateTime = DateTime.UtcNow
        Dim elapsedTime As Long = stopTime.Millisecond - startTime.Milliseco\
nd
        Console.WriteLine(elapsedTime.ToString + " milliseconds")

        Console.ReadKey()
    End Sub

End Module