refactor(remove-comments): unnecessary comments were removed and also bugs undefined variables were created in /client_server/fork.h, /client_server/udp_client.c and /client_server/udp_server.c

This commit is contained in:
Allan Julie Fontes de Oliveira 2024-11-04 18:24:11 -03:00
parent e5dad3fa8d
commit 60abb8fea7
13 changed files with 209 additions and 937 deletions

14
.gitignore vendored
View File

@ -4,3 +4,17 @@
.vscode/
build/
git_diff.txt
*.filters
*.vcxproj
*.sln
CMakeCache.txt
cmake_install.cmake
*.log
*.stamp
*.stamp.list
*.stamp.depend
*.check_cache
*.tlog
*.bin
CMakeFiles/
output/

View File

@ -1,21 +1,6 @@
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2007 - INRIA
*
* Copyright (C) 2012 - 2016 - Scilab Enterprises
*
* This file is hereby licensed under the terms of the GNU GPL v2.0,
* pursuant to article 5.3.4 of the CeCILL v.2.1.
* This file was originally licensed under the terms of the CeCILL v2.1,
* and continues to be available under such terms.
* For more information, see the COPYING file which you should have received
* along with this program.
*
*/
#ifndef __BOOL_H__
#define __BOOL_H__
/* define boolean type */
#ifdef BOOL
#undef BOOL
#endif
@ -28,8 +13,7 @@
#undef FALSE
#endif
#ifndef _MSC_VER
#ifndef _MSC_VER
typedef enum
{
FALSE = 0,
@ -37,19 +21,15 @@ typedef enum
} BOOL;
#else
/* Please notice that BOOL is defined in <windef.h> */
/* BUT windef.h includes all others windows include */
/* it is better to redefine as */
typedef int BOOL;
#define FALSE 0
#define TRUE 1
#endif
/* converts BOOL to bool */
#define BOOLtobool(w) ((w != FALSE) ? true : false)
/* converts bool to BOOL */
#define booltoBOOL(w) ((w == true) ? TRUE : FALSE)
#define BOOLtobool(w) ((w != FALSE) ? true : false)
#endif /* __BOOL_H__ */
/*--------------------------------------------------------------------------*/
#define booltoBOOL(w) ((w == true) ? TRUE : FALSE)
#endif

View File

@ -1,39 +1,26 @@
/**
* @file
* @author [Nairit11](https://github.com/Nairit11)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Client side implementation of Server-Client system.
* @see client_server/server.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define read(a, b, c) recv(a, b, c, 0) /**< map BSD name to Winsock */
#define write(a, b, c) send(a, b, c, 0) /**< map BSD name to Winsock */
#define close closesocket /**< map BSD name to Winsock */
#else // if not windows platform
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define read(a, b, c) recv(a, b, c, 0)
#define write(a, b, c) send(a, b, c, 0)
#define close closesocket
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#define MAX 80 /**< max. characters per message */
#define PORT 8080 /**< port number to connect to */
#define SA struct sockaddr /**< shortname for sockaddr */
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
/**
* Continuous loop to send and receive over the socket.
* Exits when "exit" is sent from commandline.
* @param sockfd socket handle number
*/
void func(int sockfd)
{
char buff[MAX];
@ -60,17 +47,12 @@ void func(int sockfd)
}
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/**
* @brief Driver code
*/
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
@ -78,13 +60,12 @@ int main()
return 0;
}
atexit(cleanup); // register at-exit function
atexit(cleanup);
#endif
int sockfd, connfd;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
@ -97,12 +78,10 @@ int main()
}
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
// connect the client socket to server socket
if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) != 0)
{
printf("connection with the server failed...\n");
@ -113,10 +92,8 @@ int main()
printf("connected to the server..\n");
}
// function for chat
func(sockfd);
// close the socket
close(sockfd);
return 0;
}

View File

@ -1,43 +1,22 @@
/*
* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) DIGITEO - 2010 - Allan CORNET
*
* Copyright (C) 2012 - 2016 - Scilab Enterprises
*
* This file is hereby licensed under the terms of the GNU GPL v2.0,
* pursuant to article 5.3.4 of the CeCILL v.2.1.
* This file was originally licensed under the terms of the CeCILL v2.1,
* and continues to be available under such terms.
* For more information, see the COPYING file which you should have received
* along with this program.
*
*/
/*--------------------------------------------------------------------------*/
#ifndef __FORK_H__
#define __FORK_H__
/* http://technet.microsoft.com/en-us/library/bb497007.aspx */
/* http://undocumented.ntinternals.net/ */
#include <setjmp.h>
#include <windows.h>
#include "bool.h"
/**
* simulate fork on Windows
*/
int fork(void);
/**
* check if symbols to simulate fork are present
* and load these symbols
*/
BOOL haveLoadedFunctionsForFork(void);
/*--------------------------------------------------------------------------*/
typedef LONG NTSTATUS;
/*--------------------------------------------------------------------------*/
typedef enum _THREAD_INFORMATION_CLASS
{
ThreadBasicInformation = 0,
ThreadQuerySetWin32StartAddress = 9,
ThreadMemoryPriority = 13
} THREAD_INFORMATION_CLASS;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG ProcessId;
@ -47,17 +26,17 @@ typedef struct _SYSTEM_HANDLE_INFORMATION
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
/*--------------------------------------------------------------------------*/
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PVOID /* really PUNICODE_STRING */ ObjectName;
PVOID ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */
PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
/*--------------------------------------------------------------------------*/
typedef enum _MEMORY_INFORMATION_
{
MemoryBasicInformation,
@ -65,13 +44,13 @@ typedef enum _MEMORY_INFORMATION_
MemorySectionName,
MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;
/*--------------------------------------------------------------------------*/
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
/*--------------------------------------------------------------------------*/
typedef struct _USER_STACK
{
PVOID FixedStackBase;
@ -80,11 +59,11 @@ typedef struct _USER_STACK
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
/*--------------------------------------------------------------------------*/
typedef LONG KPRIORITY;
typedef ULONG_PTR KAFFINITY;
typedef KAFFINITY *PKAFFINITY;
/*--------------------------------------------------------------------------*/
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
@ -94,22 +73,22 @@ typedef struct _THREAD_BASIC_INFORMATION
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
/*--------------------------------------------------------------------------*/
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemHandleInformation = 0x10
} SYSTEM_INFORMATION_CLASS;
/*--------------------------------------------------------------------------*/
typedef NTSTATUS(NTAPI *ZwWriteVirtualMemory_t)(
IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL);
/*--------------------------------------------------------------------------*/
typedef NTSTATUS(NTAPI *ZwCreateProcess_t)(
OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE InheriteFromProcessHandle,
IN BOOLEAN InheritHandles, IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL);
/*--------------------------------------------------------------------------*/
typedef NTSTATUS(WINAPI *ZwQuerySystemInformation_t)(
SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation,
ULONG SystemInformationLength, PULONG ReturnLength);
@ -118,7 +97,7 @@ typedef NTSTATUS(NTAPI *ZwQueryVirtualMemory_t)(
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation, IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL);
/*--------------------------------------------------------------------------*/
typedef NTSTATUS(NTAPI *ZwGetContextThread_t)(IN HANDLE ThreadHandle,
OUT PCONTEXT Context);
typedef NTSTATUS(NTAPI *ZwCreateThread_t)(
@ -126,7 +105,7 @@ typedef NTSTATUS(NTAPI *ZwCreateThread_t)(
IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext,
IN PUSER_STACK UserStack, IN BOOLEAN CreateSuspended);
/*--------------------------------------------------------------------------*/
typedef NTSTATUS(NTAPI *ZwResumeThread_t)(IN HANDLE ThreadHandle,
OUT PULONG SuspendCount OPTIONAL);
typedef NTSTATUS(NTAPI *ZwClose_t)(IN HANDLE ObjectHandle);
@ -134,7 +113,7 @@ typedef NTSTATUS(NTAPI *ZwQueryInformationThread_t)(
IN HANDLE ThreadHandle, IN THREAD_INFORMATION_CLASS ThreadInformationClass,
OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL);
/*--------------------------------------------------------------------------*/
static ZwCreateProcess_t ZwCreateProcess = NULL;
static ZwQuerySystemInformation_t ZwQuerySystemInformation = NULL;
static ZwQueryVirtualMemory_t ZwQueryVirtualMemory = NULL;
@ -144,25 +123,23 @@ static ZwResumeThread_t ZwResumeThread = NULL;
static ZwClose_t ZwClose = NULL;
static ZwQueryInformationThread_t ZwQueryInformationThread = NULL;
static ZwWriteVirtualMemory_t ZwWriteVirtualMemory = NULL;
/*--------------------------------------------------------------------------*/
#define NtCurrentProcess() ((HANDLE)-1)
#define NtCurrentThread() ((HANDLE)-2)
/* we use really the Nt versions - so the following is just for completeness */
#define NtCurrentProcess() ((HANDLE) - 1)
#define NtCurrentThread() ((HANDLE) - 2)
#define ZwCurrentProcess() NtCurrentProcess()
#define ZwCurrentThread() NtCurrentThread()
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
/*--------------------------------------------------------------------------*/
/* setjmp env for the jump back into the fork() function */
static jmp_buf jenv;
/*--------------------------------------------------------------------------*/
/* entry point for our child thread process - just longjmp into fork */
static int child_entry(void)
{
longjmp(jenv, 1);
return 0;
}
/*--------------------------------------------------------------------------*/
static BOOL haveLoadedFunctionsForFork(void)
{
HMODULE ntdll = GetModuleHandle("ntdll");
@ -214,7 +191,7 @@ static BOOL haveLoadedFunctionsForFork(void)
}
return FALSE;
}
/*--------------------------------------------------------------------------*/
int fork(void)
{
HANDLE hProcess = 0, hThread = 0;
@ -230,26 +207,19 @@ int fork(void)
if (setjmp(jenv) != 0)
{
return 0; /* return as a child */
return 0;
}
/* check whether the entry points are initilized and get them if necessary
*/
if (!ZwCreateProcess && !haveLoadedFunctionsForFork())
{
return -1;
}
/* create forked process */
ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, NtCurrentProcess(),
TRUE, 0, 0, 0);
/* set the Eip for the child process to our child function */
ZwGetContextThread(NtCurrentThread(), &context);
/* In x64 the Eip and Esp are not present, their x64 counterparts are Rip
and Rsp respectively.
*/
#if _WIN64
context.Rip = (ULONG)child_entry;
#else
@ -270,11 +240,9 @@ int fork(void)
stack.ExpandableStackLimit = mbi.BaseAddress;
stack.ExpandableStackBottom = mbi.AllocationBase;
/* create thread using the modified context and stack */
ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context,
&stack, TRUE);
/* copy exception table */
ZwQueryInformationThread(NtCurrentThread(), ThreadMemoryPriority, &tbi,
sizeof tbi, 0);
tib = (PNT_TIB)tbi.TebBaseAddress;
@ -283,16 +251,12 @@ int fork(void)
ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress, &tib->ExceptionList,
sizeof tib->ExceptionList, 0);
/* start (resume really) the child */
ZwResumeThread(hThread, 0);
/* clean up */
ZwClose(hThread);
ZwClose(hProcess);
/* exit with child's pid */
return (int)cid.UniqueProcess;
}
#endif /* __FORK_H__ */
/*--------------------------------------------------------------------------*/
#endif

View File

@ -1,113 +1,45 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Client-side implementation of [Remote Command
* Execution Using
* UDP](https://www.imperva.com/learn/ddos/udp-user-datagram-protocol/)
* @see remote_command_exec_udp_server.c
*
* @details
* The algorithm is based on the simple UDP client and server model. It
* runs an infinite loop which takes user input and sends it to the server
* for execution. The server receives the commands and executes them
* until the user exits the loop. In this way, Remote Command Execution
* using UDP is shown using the server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <winsock2.h> /// For the type in_addr_t and in_port_t
#include <winsock2.h>
#else
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <errno.h> /// To indicate what went wrong if an error occurs
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10000 /// Define port over which communication will take place
#define PORT 10000
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
char send_msg[1024],
recv_msg[1024]; ///< character arrays to read and store string data
/// for communication
uint32_t sockfd;
char send_msg[1024], recv_msg[1024];
struct sockaddr_in
server_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
socklen_t serverLength = sizeof(server_addr); ///< length of socket
struct sockaddr_in server_addr;
socklen_t serverLength = sizeof(server_addr);
/**
* The UDP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_DGRAM (Type) - Indicates UDP Connection - UDP does not require the
* source and destination to establish a three-way handshake before
* transmission takes place. Additionally, there is no need for an
* end-to-end connection
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
@ -115,29 +47,10 @@ int main()
printf("Client is running...\n");
/**
* Connects the client to the server address using the socket descriptor
* This enables the two to communicate and exchange data
*/
connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Client is Connected Successfully...\n");
/**
* Communication between client and server
*
* The client sends data to the server after taking the input
* from the user
*
* The client then receives a response from the server when the
* command has been executed
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* The client sends the server a command which it executes thus showing
* remote command execution using UDP
*/
while (1)
{
printf("\nEnter Command To Be Executed Remotely: \n");
@ -149,7 +62,6 @@ int main()
printf("Server Reply: %s\n", recv_msg);
}
/// Close Socket
close(sockfd);
printf("Client is offline...\n");
return 0;

View File

@ -1,152 +1,57 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Server-side implementation of [Remote Command
* Execution Using
* UDP](https://www.imperva.com/learn/ddos/udp-user-datagram-protocol/)
* @see remote_command_exec_udp_server.c
*
* @details
* The algorithm is based on the simple UDP client and server model. It
* runs an infinite loop which takes user input and sends it to the server
* for execution. The server receives the commands and executes them
* until the user exits the loop. In this way, Remote Command Execution
* using UDP is shown using the server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <winsock2.h> /// For the type in_addr_t and in_port_t
#include <winsock2.h>
#else
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <errno.h> /// To indicate what went wrong if an error occurs
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10000 /// Define port over which communication will take place
#define PORT 10000
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
char recv_msg[1024],
success_message[] =
"Command Executed Successfully!\n"; ///< character arrays to read
/// and store string data
/// for communication & Success
/// message
uint32_t sockfd;
char recv_msg[1024], success_message[] = "Command Executed Successfully!\n";
struct sockaddr_in server_addr,
client_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
socklen_t clientLength = sizeof(client_addr); /// size of address
struct sockaddr_in server_addr, client_addr;
socklen_t clientLength = sizeof(client_addr);
/**
* The UDP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_DGRAM (Type) - Indicates UDP Connection - UDP does not require the
* source and destination to establish a three-way handshake before
* transmission takes place. Additionally, there is no need for an
* end-to-end connection
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/**
* This binds the socket descriptor to the server thus enabling the server
* to listen for connections and communicate with other clients
*/
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error(); /// If binding is unsuccessful
error();
}
printf("Server is Connected Successfully...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* The server receives data from the client which is a command. It then
* executes the command.
*
* The client then receives a response from the server when the
* command has been executed
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* The client sends the server a command which it executes thus showing
* remote command execution using UDP
*/
while (1)
{
bzero(recv_msg, sizeof(recv_msg));
@ -159,7 +64,6 @@ int main()
(struct sockaddr *)&client_addr, clientLength);
}
/// Close socket
close(sockfd);
printf("Server is offline...\n");
return 0;

View File

@ -1,74 +1,53 @@
/**
* @file
* @author [Nairit11](https://github.com/Nairit11)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Server side implementation of Server-Client system.
* @see client_server/client.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #ifdef HAS_UNISTD
// #include <unistd.h>
// #endif
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define read(a, b, c) recv(a, b, c, 0) /**< map BSD name to Winsock */
#define write(a, b, c) send(a, b, c, 0) /**< map BSD name to Winsock */
#define close closesocket /**< map BSD name to Winsock */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define read(a, b, c) recv(a, b, c, 0)
#define write(a, b, c) send(a, b, c, 0)
#define close closesocket
#else
// if not windows platform
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#define MAX 80 /**< max. characters per message */
#define PORT 8080 /**< port number to connect to */
#define SA struct sockaddr /**< shortname for sockaddr */
#define MAX 80
#define PORT 8080
#define SA struct sockaddr
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/**
* Continuous loop to send and receive over the socket.
* Exits when "exit" is sent from commandline.
* @param sockfd socket handle number
*/
void func(int sockfd)
{
char buff[MAX];
int n;
// infinite loop for chat
for (;;)
{
bzero(buff, MAX);
// read the message from client and copy it in buffer
read(sockfd, buff, sizeof(buff));
// print buffer which contains the client contents
printf("From client: %s\t To client : ", buff);
bzero(buff, MAX);
n = 0;
// copy server message in the buffer
while ((buff[n++] = getchar()) != '\n')
{
;
}
// and send that buffer to client
write(sockfd, buff, sizeof(buff));
// if msg contains "Exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0)
{
printf("Server Exit...\n");
@ -77,11 +56,9 @@ void func(int sockfd)
}
}
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
@ -89,14 +66,13 @@ int main()
return 0;
}
atexit(cleanup); // register at-exit function
atexit(cleanup);
#endif
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
// socket create and verification
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
@ -109,12 +85,10 @@ int main()
}
bzero(&servaddr, sizeof(servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// Binding newly created socket to given IP and verification
if ((bind(sockfd, (SA *)&servaddr, sizeof(servaddr))) != 0)
{
perror("socket bind failed...\n");
@ -125,7 +99,6 @@ int main()
printf("Socket successfully binded..\n");
}
// Now server is ready to listen and verification
if ((listen(sockfd, 5)) != 0)
{
perror("Listen failed...\n");
@ -137,7 +110,6 @@ int main()
}
len = sizeof(cli);
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA *)&cli, &len);
if (connfd < 0)
{
@ -149,10 +121,8 @@ int main()
printf("server acccept the client...\n");
}
// Function for chatting between client and server
func(connfd);
// After chatting close the socket
close(sockfd);
return 0;
}

View File

@ -1,119 +1,47 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Client-side implementation of [TCP Full Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_full_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send and receive data simultaneously. This is
* implemented by using the `fork` function call so that in the server the child
* process can receive data and parent process can send data, and in the client
* the child process can send data and the parent process can receive data. It
* runs an infinite loop and can send and receive messages indefinitely until
* the user exits the loop. In this way, the Full Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define pid_t int
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <windows.h>
#include <winsock2.h>
#include "fork.h"
#define sleep(a) Sleep(a * 1000)
#else
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10000 /// Define port over which communication will take place
#define PORT 10000
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
char sendbuff[1024],
recvbuff[1024]; ///< character arrays to read and store string data
/// for communication
uint32_t sockfd;
char sendbuff[1024], recvbuff[1024];
struct sockaddr_in
server_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
struct sockaddr_in server_addr;
/**
* The TCP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes.
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
@ -121,41 +49,14 @@ int main()
printf("Client is running...\n");
/**
* Connects the client to the server address using the socket descriptor
* This enables the two to communicate and exchange data
*/
connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Client is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* The fork function call is used to create a child and parent process
* which run and execute code simultaneously
*
* The child process is used to send data and after doing so
* sleeps for 5 seconds to wait for the parent to receive data
*
* The parent process is used to receive data and after doing so
* sleeps for 5 seconds to wait for the child to send data
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* Since the exchange of information between the server and client takes
* place simultaneously this represents FULL DUPLEX COMMUNICATION
*/
pid_t pid;
pid = fork();
if (pid == 0) /// Value of 0 is for child process
if (pid == 0)
{
while (1)
{
@ -165,10 +66,9 @@ int main()
send(sockfd, sendbuff, strlen(sendbuff) + 1, 0);
printf("\nMessage sent!\n");
sleep(5);
// break;
}
}
else /// Parent Process
else
{
while (1)
{
@ -176,11 +76,9 @@ int main()
recv(sockfd, recvbuff, sizeof(recvbuff), 0);
printf("\nSERVER: %s\n", recvbuff);
sleep(5);
// break;
}
}
/// Close Socket
close(sockfd);
printf("Client is offline...\n");
return 0;

View File

@ -1,121 +1,49 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Server-side implementation of [TCP Full Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_full_duplex_client.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send and receive data simultaneously. This is
* implemented by using the `fork` function call so that in the server the child
* process can receive data and parent process can send data, and in the client
* the child process can send data and the parent process can receive data. It
* runs an infinite loop and can send and receive messages indefinitely until
* the user exits the loop. In this way, the Full Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define pid_t int
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <windows.h>
#include <winsock2.h>
#include "fork.h"
#define sleep(a) Sleep(a * 1000)
#else
#include <arpa/inet.h> /// For the type in_addr_t and in_port_t
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10000 /// Define port over which communication will take place
#define PORT 10000
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t sockfd,
conn; ///< socket descriptors - Like file handles but for sockets
char recvbuff[1024],
sendbuff[1024]; ///< character arrays to read and store string data
/// for communication
uint32_t sockfd, conn;
char recvbuff[1024], sendbuff[1024];
struct sockaddr_in server_addr,
client_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
socklen_t ClientLen; /// size of address
struct sockaddr_in server_addr, client_addr;
socklen_t ClientLen;
/**
* The TCP socket is created using the socket function
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error(); ///< Error if the socket descriptor has a value lower than 0 -
/// socket wasnt created
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
@ -123,68 +51,30 @@ int main()
printf("Server is running...\n");
/**
* This binds the socket descriptor to the server thus enabling the server
* to listen for connections and communicate with other clients
*/
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error(); /// If binding is unsuccessful
error();
}
/**
* This is to listen for clients or connections made to the server
*
* The limit is currently at 5 but can be increased to listen for
* more connections
*
* It listens to connections through the socket descriptor
*/
listen(sockfd, 5);
printf("Server is listening...\n");
/**
* When a connection is found, a socket is created and connection is
* accepted and established through the socket descriptor
*/
conn = accept(sockfd, (struct sockaddr *)NULL, NULL);
printf("Server is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* The fork function call is used to create a child and parent process
* which run and execute code simultaneously
*
* The child process is used to receive data and after doing so
* sleeps for 5 seconds to wait for the parent to send data
*
* The parent process is used to send data and after doing so
* sleeps for 5 seconds to wait for the child to receive data
*
* The server and client can communicate indefinitely till one of them
* exits the connection
*
* Since the exchange of information between the server and client takes
* place simultaneously this represents FULL DUPLEX COMMUNICATION
*/
pid_t pid;
#ifdef _WIN32
#ifdef FORK_WINDOWS
#ifdef _WIN32
#ifdef FORK_WINDOWS
pid = fork();
#endif
#else
#endif
#else
pid = fork();
#endif
#endif
if (pid == 0) /// Value of 0 is for child process
if (pid == 0)
{
while (1)
{
@ -192,10 +82,9 @@ int main()
recv(conn, recvbuff, sizeof(recvbuff), 0);
printf("\nCLIENT : %s\n", recvbuff);
sleep(5);
// break;
}
}
else /// Parent process
else
{
while (1)
{
@ -205,11 +94,9 @@ int main()
send(conn, sendbuff, strlen(sendbuff) + 1, 0);
printf("\nMessage Sent!\n");
sleep(5);
// break;
}
}
/// Close socket
close(sockfd);
printf("Server is offline...\n");
return 0;

View File

@ -1,111 +1,40 @@
/**
* @file
* @author [Nikhill Vombatkere](https://github.com/NVombat)
* @brief Client-side implementation of [TCP Half Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_half_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* the server and client can both send data but only one at a time. This is
* implemented by using a particular ordering of the `send()` and `recv()`
* functions. When one of the clients or servers is sending, the other can only
* receive and vice-versa. In this way, the Half Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <winsock2.h>
#else
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
// #include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8100 /// Define port over which communication will take place
#define PORT 8100
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t
sockfd; ///< socket descriptors - Like file handles but for sockets
struct sockaddr_in
server_addr; ///< basic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
char serverResponse[10000],
clientResponse[10000]; ///< Character arrays to read and store string
/// data for communication
uint32_t sockfd;
struct sockaddr_in server_addr;
char serverResponse[10000], clientResponse[10000];
/**
* The TCP socket is created using the socket function.
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes.
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type.
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area.
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
@ -113,49 +42,23 @@ int main()
printf("Client is running...\n");
/**
* Connects the client to the server address using the socket descriptor
* This enables the two to communicate and exchange data
*/
connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Client is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* First the CLIENT receives the servers message and displays it (recv())
*
* The CLIENT is then prompted to type in a message and send it to the
* server. (send())
*
* The server and client can communicate till one of them exits the
* connection
*
* Since the exchange of information between the server and client take
* place one at a time this represents HALF DUPLEX COMMUNICATION
*/
while (1)
{
bzero(&serverResponse, sizeof(serverResponse));
bzero(&clientResponse, sizeof(clientResponse));
/// Receive Message
recv(sockfd, serverResponse, sizeof(serverResponse), 0);
printf("\nServer message: %s \n", serverResponse);
/// Send Message
printf("\nEnter message here: ");
fgets(clientResponse, 10000, stdin);
send(sockfd, clientResponse, strlen(clientResponse) + 1, 0);
}
/// Close Socket
close(sockfd);
printf("Client is offline...\n");
return 0;

View File

@ -1,185 +1,73 @@
/**
* @file
* @author [NVombat](https://github.com/NVombat)
* @brief Server-side implementation of [TCP Half Duplex
* Communication](http://www.tcpipguide.com/free/t_SimplexFullDuplexandHalfDuplexOperation.htm)
* @see tcp_half_duplex_server.c
*
* @details
* The algorithm is based on the simple TCP client and server model. However,
* instead of the server only sending and the client only receiving data,
* The server and client can both send data but only one at a time. This is
* implemented by using a particular ordering of the `send()` and `recv()`
* functions. When one of the clients or servers is sending, the other can only
* receive and vice-versa. In this way, the Half Duplex Form of communication
* can be represented using the TCP server-client model & socket programming
*/
#ifdef _WIN32
#define bzero(b, len) \
(memset((b), '\0', (len)), (void)0) /**< BSD name not in windows */
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#define close _close
#include <Ws2tcpip.h>
#include <io.h>
#include <winsock2.h>
#else
#include <netdb.h> /// For structures returned by the network database library - formatted internet addresses and port numbers
#include <sys/socket.h> /// For macro definitions related to the creation of sockets
#include <sys/types.h> /// For definitions to allow for the porting of BSD programs
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
// #include <netinet/in.h> /// For in_addr and sockaddr_in structures
#include <stdint.h> /// For specific bit size values of variables
#include <stdio.h> /// Variable types, several macros, and various functions for performing input and output
#include <stdlib.h> /// Variable types, several macros, and various functions for performing general functions
#include <string.h> /// Various functions for manipulating arrays of characters
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8100 /// Define port over which communication will take place
#define PORT 8100
/**
* @brief Utility function used to print an error message to `stderr`.
* It prints `str` and an implementation-defined error
* message corresponding to the global variable `errno`.
* @returns void
*/
void error()
{
perror("Socket Creation Failed");
exit(EXIT_FAILURE);
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main()
{
/** Variable Declarations */
uint32_t sockfd,
conn; ///< socket descriptors - Like file handles but for sockets
char server_msg[10000],
client_msg[10000]; ///< character arrays to read and store string data
/// for communication
struct sockaddr_in server_addr,
client_addr; ///< asic structures for all syscalls and functions that
/// deal with internet addresses. Structures for handling
/// internet addresses
uint32_t sockfd, conn;
char server_msg[10000], client_msg[10000];
struct sockaddr_in server_addr, client_addr;
/**
* The TCP socket is created using the socket function
*
* AF_INET (Family) - it is an address family that is used to designate the
* type of addresses that your socket can communicate with
*
* SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
* for the bidirectional, reliable, sequenced, and unduplicated flow of data
* without record boundaries. Aside from the bidirectionality of data flow,
* a pair of connected stream sockets provides an interface nearly identical
* to pipes
*
* 0 (Protocol) - Specifies a particular protocol to be used with the
* socket. Specifying a protocol of 0 causes socket() to use an unspecified
* default protocol appropriate for the requested socket type
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error(); ///< Error if the socket descriptor has a value lower than 0 -
/// socket wasnt created
error();
}
/**
* Server Address Information
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area
*
* We bind the server_addr to the internet address and port number thus
* giving our socket an identity with an address and port where it can
* listen for connections
*
* htons - The htons() function translates a short integer from host byte
* order to network byte order
*
* htonl - The htonl() function translates a long integer from host byte
* order to network byte order
*
* These functions are necessary so that the binding of address and port
* takes place with data in the correct format
*/
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET; /// Domain/Family to be used
server_addr.sin_port = htons(PORT); /// Port to be used
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
printf("Server is running...\n");
/**
* This binds the socket descriptor to the server thus enabling the server
* to listen for connections and communicate with other clients
*/
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
error(); /// If binding is unsuccessful
error();
}
/**
* This is to listen for clients or connections made to the server
*
* The limit is currently at 5 but can be increased to listen for
* more connections
*
* It listens to connections through the socket descriptor
*/
listen(sockfd, 5);
printf("Server is listening...\n");
/**
* When a connection is found, a socket is created and connection is
* accepted and established through the socket descriptor
*/
conn = accept(sockfd, (struct sockaddr *)NULL, NULL);
printf("Server is connected...\n");
/**
* Communication between client and server
*
* The bzero() function erases the data in the n bytes of the memory
* starting at the location pointed to, by writing zeros (bytes
* containing '\0') to that area. The variables are emptied and then
* ready for use
*
* First the SERVER is prompted to type a message which is read from
* stdin and then sent over the connection that was established - the socket
* - to be received by the client (send())
*
* The SERVER then waits for the client to reply. It then receives the reply
* in the string variable and displays it (recv())
*
* The server and client can communicate till one of them exits the
* connection
*
* Since the exchange of information between the server and client take
* place one at a time this represents HALF DUPLEX COMMUNICATION
*/
while (1)
{
bzero(&server_msg, sizeof(server_msg));
bzero(&client_msg, sizeof(client_msg));
/// Send message
printf("\nEnter message here: ");
fgets(server_msg, 10000, stdin);
send(conn, server_msg, strlen(server_msg) + 1, 0);
/// Receive Message
recv(conn, client_msg, sizeof(client_msg), 0);
printf("\nClient Message: %s\n", client_msg);
}
/// Close socket
close(sockfd);
printf("Server is offline...\n");
return 0;

View File

@ -1,16 +1,9 @@
/**
* @file
* @author [TheShubham99](https://github.com/TheShubham99)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Client side implementation of UDP client-server model
* @see client_server/udp_server.c
*/
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#define close closesocket /**< map BSD name to Winsock */
#else // if not windows platform
#define close closesocket
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
@ -23,19 +16,16 @@
#include <stdlib.h>
#include <string.h>
#define PORT 8080 /**< port number to connect to */
#define MAXLINE 1024 /**< maximum characters per line */
#define PORT 8080
#define MAXLINE 1024
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
@ -43,7 +33,7 @@ int main()
return 0;
}
atexit(cleanup); // register at-exit function
atexit(cleanup);
#endif
int sockfd;
@ -51,7 +41,6 @@ int main()
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket creation failed");
@ -60,7 +49,6 @@ int main()
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
@ -72,7 +60,7 @@ int main()
(const struct sockaddr *)&servaddr, sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL,
n = recvfrom(sockfd, (char *)buffer, MAXLINE, 0,
(struct sockaddr *)&servaddr, &len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);

View File

@ -1,16 +1,8 @@
/**
* @file
* @author [TheShubham99](https://github.com/TheShubham99)
* @author [Krishna Vedala](https://github.com/kvedala)
* @brief Server side implementation of UDP client-server model
* @see client_server/udp_client.c
*/
#ifdef _WIN32 // if compiling for Windows
#define _WINSOCK_DEPRECATED_NO_WARNINGS // will make the code invalid for next
// MSVC compiler versions
#define close closesocket /**< map BSD name to Winsock */
#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define close closesocket
#include <winsock2.h>
#else // if not windows platform
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
@ -23,19 +15,17 @@
#include <stdlib.h>
#include <string.h>
#define PORT 8080 /**< port number to connect to */
#define MAXLINE 1024 /**< maximum characters per line */
#define PORT 8080
#define MAXLINE 1024
#ifdef _WIN32
/** Cleanup function will be automatically called on program exit */
void cleanup() { WSACleanup(); }
#endif
/** Driver code */
int main()
{
#ifdef _WIN32
// when using winsock2.h, startup required
WSADATA wsData;
if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
{
@ -43,7 +33,7 @@ int main()
return 0;
}
atexit(cleanup); // register at-exit function
atexit(cleanup);
#endif
int sockfd;
@ -51,7 +41,6 @@ int main()
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket creation failed");
@ -61,12 +50,10 @@ int main()
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind failed");
@ -75,7 +62,7 @@ int main()
unsigned int len;
int n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL,
n = recvfrom(sockfd, (char *)buffer, MAXLINE, 0,
(struct sockaddr *)&cliaddr, &len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);