Just for info: I run server and client in seperate virtual machines.
I have posted the code for client and server:
client:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
int main(int argc, char *argv[]) {
if (argc < 3 || argc > 4) // Test for correct number of arguments
DieWithUserMessage("Parameter(s)",
"<Server Address> <Echo Word> [<Server Port>]");
char *servIP = argv[1]; // First arg: server IP address (dotted quad)
char *echoString = argv[2]; // Second arg: string to echo
// Third arg (optional): server port (numeric). 7 is well-known echo port
in_port_t servPort = (argc == 4) ? atoi(argv[3]) : 7;
// Create a reliable, stream socket using TCP
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
DieWithSystemMessage("socket() failed");
// Construct the server address structure
struct sockaddr_in servAddr; // Server address
memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
servAddr.sin_family = AF_INET; // IPv4 address family
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr);
if (rtnVal == 0)
DieWithUserMessage("inet_pton() failed", "invalid address string");
else if (rtnVal < 0)
DieWithSystemMessage("inet_pton() failed");
servAddr.sin_port = htons(servPort); // Server port
// Establish the connection to the echo server(socket of echo server)
if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("connect() failed");
//print local address
struct sockaddr_in clntAddrLcl; // client address
memset(&clntAddrLcl, 0, sizeof(clntAddrLcl)); // Zero out structure
clntAddrLcl.sin_family = AF_INET; // IPv4 address family
int size = sizeof(clntAddrLcl);
getsockname(sock, (struct sockaddr *) &clntAddrLcl, &size);
fputs("client address after connect: ", stdout);
PrintSocketAddress((struct sockaddr *) &clntAddrLcl, stdout);
fputc('\n',stdout);
//print foreign address
struct sockaddr_in clntAddrFor; // foreign address
memset(&clntAddrFor, 0, sizeof(clntAddrFor)); // Zero out structure
clntAddrFor.sin_family = AF_INET; // IPv4 address family
int size2 = sizeof(clntAddrFor);
getpeername(sock, (struct sockaddr *) &clntAddrFor, &size2);
fputs("address of server(peer of client) after connect: ", stdout);
PrintSocketAddress((struct sockaddr *) &clntAddrFor, stdout);
fputc('\n', stdout);
size_t echoStringLen = strlen(echoString); // Determine input length
//now client can send data to server
// Send the string to the server over client sock
unsigned int numBytes = send(sock, echoString, echoStringLen, 0);
if (numBytes < 0)
DieWithSystemMessage("send() failed");
else if (numBytes != echoStringLen)
DieWithUserMessage("send()", "sent unexpected number of bytes");
// Receive the same string back from the server
unsigned int totalBytesRcvd = 0; // Count of total bytes received // Count of total bytes received
//fputs("\nReceived(clnt): \n", stdout); // Setup to print the echoed string
while (totalBytesRcvd < echoStringLen) {
char buffer[BUFSIZE]; // I/O buffer
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
//receive message on clientsock
numBytes = recv(sock, buffer, BUFSIZE - 1, 0);
if (numBytes < 0)
DieWithSystemMessage("recv() failed");
else if (numBytes == 0)
DieWithUserMessage("recv()", "connection closed prematurely");
totalBytesRcvd += numBytes; // Keep tally of total bytes
buffer[numBytes] = '\0'; // Terminate the string!
//fputs(buffer, stdout); // Print the echo buffer
}
fputc('\n', stdout); // Print a final linefeed
close(sock);
exit(0);
}
server:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Practical.h"
static const int MAXPENDING = 5; // Maximum outstanding connection requests
int main(int argc, char *argv[]) {
if (argc != 2) // Test for correct number of arguments
DieWithUserMessage("Parameter(s)", "<Server Port>");
in_port_t servPort = atoi(argv[1]); // First arg: local port
// Create socket for incoming connections
int servSock; // Socket descriptor for server
if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithSystemMessage("socket() failed");
// Construct local address structure
struct sockaddr_in servAddr; // Local address
memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
servAddr.sin_family = AF_INET; // IPv4 address family
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
servAddr.sin_port = htons(servPort); // Local port
// Bind to the local address
if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("bind() failed");
// Mark the socket so it will listen for incoming connections
if (listen(servSock, MAXPENDING) < 0)
DieWithSystemMessage("listen() failed");
for (;:wink: { // Run forever
struct sockaddr_in clntAddr; // Client address
// Set length of client address structure (in-out parameter)
socklen_t clntAddrLen = sizeof(clntAddr);
// Wait for a client to connect
int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
if (clntSock < 0)
DieWithSystemMessage("accept() failed");
//print address of clntsocket
struct sockaddr_in clntAddrLcl; // client address
memset(&clntAddrLcl, 0, sizeof(clntAddrLcl)); // Zero out structure
clntAddrLcl.sin_family = AF_INET; // IPv4 address family
int size = sizeof(clntAddrLcl);
getsockname(clntSock, (struct sockaddr *) &clntAddrLcl, &size);
fputs("address of clntSock after accept: ", stdout);
PrintSocketAddress((struct sockaddr *) &clntAddrLcl, stdout);
fputc('\n',stdout);
//print address of peer of clntsocket
struct sockaddr_in clntAddrFor; // client address
memset(&clntAddrFor, 0, sizeof(clntAddrFor)); // Zero out structure
clntAddrFor.sin_family = AF_INET; // IPv4 address family
int size2 = sizeof(clntAddrFor);
getpeername(clntSock, (struct sockaddr *) &clntAddrFor, &size2);
fputs("address of peer of clntSock after accept: ", stdout);
PrintSocketAddress((struct sockaddr *) &clntAddrFor, stdout);
fputc('\n', stdout);
// clntSock is connected to a client!
char clntName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName,
sizeof(clntName)) != NULL)
printf("Handling client %s/%d\n", clntName, ntohs(clntAddr.sin_port));
else
puts("Unable to get client address");
HandleTCPClient(clntSock);
}
// NOT REACHED
}