Java Network Programming Buyer/Seller Telnet Application

Share This:

SellConnection class:

package buyersellerprogram.server;

import java.net.Socket;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;

import buyersellerprogram.bargainer.Seller;

public class SellConnection extends Thread {

Socket connection;
Seller seller;

public SellConnection(Socket s, Seller sellerIn) {
//** Set the value of the Socket to s
connection = s;
//** Set the value of the global seller to the local constructor seller
seller = sellerIn;
}

public void run() {
try {
String line = “”;
System.out.println(“Using seller:\n” + seller.getSellerName());
//** Get the input stream for the socket
InputStream conn_is = connection.getInputStream();
//** Create a new InputStreamReader on the socket input stream connection
InputStreamReader isr = new InputStreamReader(conn_is);
//** Create a new BufferedReader (in) on the InputStreamReader
BufferedReader in = new BufferedReader(isr);
//** Get the socket output stream and assign its value to the variable (out)
OutputStream out = connection.getOutputStream();

//** Read a line from the BufferedReader and assign its value to a String variable line
line = in.readLine();

int numTokens = 0;
String command = null;
String errorResponse;
boolean finished = false;
if (handShake(line, out, seller)) {

do {
//** Set the value of the variable line to a line read from the BufferedReader
line = in.readLine();

errorResponse = “”;
//** Create a variable st of type StringTokenizer to use to Tokenize the line
StringTokenizer st = new StringTokenizer(line);

if (!st.hasMoreTokens()) {
//** Set the value of the (errorResponse) variable, .. we were sent an empty message
errorResponse = “we were sent an empty message.”;
} else {
// There is at least one word on the line
//** Set the value of the (command) to the next token
command = st.nextToken();
if (st.hasMoreTokens()) {
// there are at least two words on the line
// we will read the second and ignore any others
// first, the only command with two arguments is “bid p”
//** Check if the command is not equal to “bib”
if (!command.equals(“bid”)) {
//** Set the value of the (errorResponse) to Incorrect error message
errorResponse = “Incorrect command.”;
} else {
// The command was bid so find out the price
try {
//** The next token read is the bid amount
//** Assign it’s value to a variable (price)
int price = Integer.parseInt(st.nextToken());
seller.getHistory().buyerBid(price);
// a valid integer price
// ask our seller to respond
String response = seller.respondToBid(price);
//** Set the value of the String variable (response)
//** to the seller response for bid
//** If the seller accepted or rejected, we’re finished
if (seller.getState() == seller.ACCEPTED || seller.getState() == seller.REJECTED){
finished = true;
}
//** Send the response back to the client followed by a carriage return
out.write(response.getBytes());
//** Flush the output stream
out.flush();

if (!finished) {
//** Get the response to our offer set the value of line
//** to the line read from input stream
//line = in.readLine();
}
} catch (NumberFormatException e) {
// the argument to “bid” was not an integer
//** Set the value errorResponse to the error
//** corresponding to no price
errorResponse = “Price not found.”;
// error no price
}
}
} else {
// accept or reject
if (command.equals(“accept”)) {
// if we offered something to accept
if (seller.getHistory().getNumOffersToSell() > 0) {
//** Set seller state to offer accepted
seller.setState(seller.OFFERACCEPTED);
finished = true;
} else {
// no offers, so nothing to accept
//** Set the value errorResponse
errorResponse = “No offers, so nothing to accept\n”;

}
} else if (command.equals(“reject”)) {
//** Set seller state to offer rejected
seller.setState(seller.OFFERREJECTED);
finished = true;
} else {
//** Set the value errorResponse. Should be either accept/reject
errorResponse = “Should be either accept/reject\n”;
}
}

}
if (errorResponse.length() > 0) {
//** write the errorResponse to the output stream as bytes followed by a
//**  an empty line and a carriage return
out.write(errorResponse.getBytes());
//** flush the output stream
out.flush();
}

//** Get the response from the input stream and set the value of line
//** line to the line read from the input stream
//line = in.readLine();

} while (!finished);
}
} catch (NullPointerException e) {
System.err.println(“Got null from the client\n” + e);
} catch (IOException e) {
System.err.println(“error doing IO”);
System.out.println(e);
} finally {
System.out.println(seller);
try {
System.out.println(“Closing connection at the seller end”);
if (connection != null) {
connection.close();
}
} catch (IOException e) { System.out.println(“Error closing connection\n”); }
}
}

//** set the arguments for the handShake method
private boolean handShake(String lineIn, OutputStream outIn, Seller sellerIn) throws IOException {
if (lineIn.startsWith(“hello “)) {
int i = lineIn.indexOf(‘ ‘);
String buyerName = lineIn.substring(i+1);
sellerIn.setBuyerName(buyerName);

//** Set the text of the response from the seller
String response = “hello ” + sellerIn.getSellerName() + “\r\n”;
//** write the response to output stream as bytes followed by a
//**  an empty line and a carriage return
outIn.write(response.getBytes());

//** flush the output stream
outIn.flush();

return true;
} else {
//** Send an errorResponse hello is not correct
String err = “hello is not correct\n\r\n”;
//** write the response to output stream as bytes followed by a
//**  an empty line and a carriage return and flush the output stream
outIn.write(err.getBytes());
outIn.flush();

return false;
}}}

SellServ class:

 

package buyersellerprogram.server;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.lang.IllegalArgumentException;

import buyersellerprogram.bargainer.*;

public class SellServ {

/**
* default port is 9191
*/
public static final int DEFAULT_PORT = 9198;
int port;

/**
* Get the value of port.
* @return value of port.
*/
public int getPort() {
return port;
}

/**
* Set the value of port.
* @param v  Value to assign to port.
*/
public void setPort(int  v) {
this.port = v;
}

/**
* Construct a new object of type SellServ
*/
public SellServ(int port) {
this.port = port;
}

/**
* Start the network service
*/
public void startService() {
ServerSocket serverSocket = null;
Socket clientConnection = null;
try {

//** create the server socket (serverSocket)
ServerSocket server = new ServerSocket(port);

System.out.println(“Starting Network Selling service on port ” +
port);

System.out.println(“Accepting connections…”);
while (true) {

//** (clientConnection) awaits connections on the server socket
clientConnection = server.accept();
System.out.println(“Accepted from ” + clientConnection.getInetAddress());

//** new connection so create a new SellConnection thread to handle the connection
SellConnection sc = new SellConnection(clientConnection, chooseSeller());
sc.start();
}

} catch (IOException e) {
System.out.println(e);
} finally {
System.out.println(“Sell Server closing down”);

//** close the server socket and catch exceptions
if(serverSocket !=null){
try {
serverSocket.close();
} catch (IOException e) {}
}
}
}

public static void main(String[] args) {
SellServ sell = null;
if (args.length > 1) {
throw new IllegalArgumentException(“Usage: Echo [port]”);
} else if (args.length == 0) {
sell = new SellServ(DEFAULT_PORT);
} else {
sell = new SellServ(Integer.parseInt(args[0]));
}
sell.startService();
}

private Seller chooseSeller() {
//** returns a new object of your seller class
return new YourSeller(“Your Seller”);
}

}
YourSeller class:
package buyersellerprogram.server;

import buyersellerprogram.bargainer.Seller;
import java.util.Random;

//Create Your Seller class i.e YourSeller that extends Seller and implement makeResponce
public class YourSeller extends Seller{

//constructor for YourSeller and calls supper that say “hello, YourSeller”
public YourSeller(String name) {
super(name);
}

//implement makeResponce return string (accept, reject or offer) / (based on price, number of days)
public String makeResponse(int price){

//get cost ?helps to find the offer?
//get number of days to sell
//set state (accept, reject or offer) based on price and number of days
final int NUMDAYSTOSELL = this.getNumDaysToSell();

//Declare a variable MAXNUMOCCURRENCES to store the maximum occurrences of
//a particular bid.
final int MAXNUMOCCURRENCES = 4;

//Declare a variable numOccurrences to store the number of occurrences of
//a paticular bid. Initialise it to zero.
int numOccurrences = 0;

//Declare an integer call lastOffer and set it to zero
int lastOffer = 0;

//Declare an integer name offer to store each offer made by the seller
int offer;

//Declare an integer name acceptedBid to store a bid that the seller will
//accept that is not equal to the offer. Initialise to zero.
int acceptedBid = 0;

//Set the state to REJECTED;
this.setState(DEALING);

//Calculate new offer.
//If there were no previous offers, then offer depends on COST.
//Else offer depends on price.
if(this.history.getNumOffersToSell() == 0){
//Calculate the first offer
offer = (this.getCost() + (NUMDAYSTOSELL/2));
}
else { //Calculate subsequent offers
lastOffer = this.history.getLastSellerOffer();

//If the buyer has bid higher than or equal to the last offer,
//then offer becomes the price. Else calculate a new offer based
//on price and lastOffer.
if (price >= lastOffer)
offer = price;
else
offer = (price + ((lastOffer – price)/2));
}

//Calculate an integer that the seller is ready to accept and store it in
//acceptedBid. This integer depends on the value of the last offer and the
//calculation is lastOffer – (a random number between 1 and 3)
acceptedBid = lastOffer – (new Random().nextInt(3));

//Get the number of occurrences of a bid value
for (int i = 0; i < this.history.getNumBidsToBuy(); i++){
if(price == this.history.getBuyerBid(i))
numOccurrences++;
}

//If price is not within the accepted range then notify the buyer
if((price < MINCOST) || (price > MAXCOST))
{
return “Minimum bid is ” + MINCOST + “.\n” +
“Maximum bid is ” + MAXCOST + “.\n”;
//Else accept the bid if it equals acceptedBid or offer.
} else if ((price == acceptedBid || price == offer)){
this.setState(ACCEPTED);
}
//Else if the buyer is persistent with a particular bid then accept or
//reject based on the number of days to sell.
else if(numOccurrences >= MAXNUMOCCURRENCES){
if(NUMDAYSTOSELL >= MINDTS)
this.setState(REJECTED);
else
this.setState(ACCEPTED);
}
//Else send an offer to the buyer
else {
//Send the offer to the transaction history
this.history.sellerOffer(offer);
}
/*==== 3 IF statements =====
if statements accept
if statement reject
if statement next offer
*/
if(this.getState() == ACCEPTED)
return “bid accepted\n”;
else if (this.getState() == REJECTED)
return “bid rejected\n”;
else
return “offer ” + offer + “\n”;
}
}

Two neccessery classes by A.R.Tawil
Seller class:

package buyersellerprogram.bargainer;

import java.util.Random;

/**
* An abstract class to model a seller in the CN3044 coursework
* involving bargaining between buyers and sellers.  A Seller has a
* cost and a number of days to sell.  It will maintain a history of
* bids received and offers made.  In order to use a Seller in your
* program, you need to extend the Seller class and implement your
* strategy for making offers.  To do that you implement the method
* <tt>makeResponse</tt>.
* @author Dr A R Tawil (c) 2010
* @version 1.0
*/
public abstract class Seller {

/**
* The minimum value for the buyer’s cost.
*/
public static final int MINCOST = 10;
/**
* The maximum value for the buyer’s cost.
*/
public static final int MAXCOST = 50;
/**
* The range of the buyer’s cost.
*/
public static final int COSTRANGE = MAXCOST – MINCOST;
/**
* The minimum value for the number of days to sell.
*/
public static final int MINDTS = 3;
/**
* The maximum value for the number of days to sell.
*/
public static final int MAXDTS = 20;
/**
* The range of the number of days to sell.
*/
public static final int DTSRANGE = MAXDTS – MINDTS;
/**
* A multiplier value for use in the buyers strategy.
*/
public static final double DEFAULTMULTIPLIER = 1.5;
/**
* The default name for a seller.
*/
public static final String DEFAULTNAME = “Default Seller”;

/**
* Used to model the state of the bargaining process.  DEALING means
* no deal reached yet..
*/
public static final int DEALING = 0;
/**
* Used to model the state of the bargaining process.  ACCEPTED
* means that this seller has accepted a bid from the buyer.
*/
public static final int ACCEPTED = 1;
/**
* Used to model the state of the bargaining process.  REJECTED
* means that this seller has rejected a bid from the buyer.
*/
public static final int REJECTED = 2;
/**
* Used to model the state of the bargaining process.  BIDACCEPTED
* means that the buyer has accepted this seller’s last offer.
*/
public static final int OFFERACCEPTED = 3;
/**
* Used to model the state of the bargaining process.  OFFERREJECTED
* means that the buyer has rejected this seller’s offers.
*/
public static final int OFFERREJECTED = 4;

private Random rand;
private int cost;
private int numDaysToSell;
private String sellerName;
private double multiplier;
private int state;
protected TransactionHistory history;
private String buyerName;

/**
* Get the value of buyerName.
* The Buyer is the person we are dealing with.
* @return value of buyerName.
*/
public String getBuyerName() {
return buyerName;
}

/**
* Set the value of buyerName.
* The Buyer is the person we are dealing with.
* @param v  Value to assign to buyerName.
*/
public void setBuyerName(String  v) {
this.buyerName = v;
}

/**
* Get the value of history.
* @return value of history.
*/
public TransactionHistory getHistory() {
return history;
}

/**
* Get the value of state.
* @return value of state.
*/
public int getState() {
return state;
}

/**
* Set the value of state.
* @param v  Value to assign to state.
*/
public void setState(int  v) {
this.state = v;
}

/**
* Get the value of multiplier.
* @return value of multiplier.
*/
public double getMultiplier() {
return multiplier;
}

/**
* Set the value of multiplier.
* @param v  Value to assign to multiplier.
*/
public void setMultiplier(double  v) {
this.multiplier = v;
}

/**
* Get the value of sellerName.
* The variable holds the name of this seller.
* @return value of sellerName.
*/
public String getSellerName() {
return sellerName;
}

/**
* Get the value of numDaysToSell.
* @return value of numDaysToSell.
*/
public int getNumDaysToSell() {
return numDaysToSell;
}

/**
* Get the value of cost.
* @return value of cost.
*/
public int getCost() {
return cost;
}

/**
* reset the buyer back to its starting state, clearing the history
*/
public void reset() {
state = DEALING;
cost = rand.nextInt(COSTRANGE) + MINCOST;
numDaysToSell = rand.nextInt(DTSRANGE) + MINDTS;
history.reset();
}

/**
* construct a new Buyer with a default name, a random cost and
* random number of days to sell.
*/
private Seller() {
history = new TransactionHistory();
state = DEALING;
rand = new Random();
cost = rand.nextInt(COSTRANGE) + MINCOST;
numDaysToSell = rand.nextInt(DTSRANGE) + MINDTS;
multiplier = DEFAULTMULTIPLIER;
this.sellerName = DEFAULTNAME;
buyerName = “UNKNOWN”;
}

/**
* construct a new Buyer with a specified name, default multiplier,
* a random cost and random number of days to sell.
* @param name The name for this Seller.
*/
public Seller(String name) {
this();
this.sellerName = name;
}

/**
* construct a new Buyer with a specified name and multiplier value,
* a random cost and random number of days to sell.
* @param name The name for this Seller.
* @param multiplier The value for the multiplier.
*/
public Seller(String name, double multiplier) {
this();
this.sellerName = name;
setMultiplier(multiplier);
}

/**
* Respond to a bid of <tt>price</tt> price.
* @param price The value of the bid.
* @return A string to be used as the response to the bid.  For
* example <tt>offer 30</tt>.
*/
public String respondToBid(int price) {
String command;
if (numDaysToSell == 0) {
command = “reject”;
this.state = REJECTED;
} else {
command = makeResponse(price);
numDaysToSell–;
}
return command;
}

/**
* Implement this method to make your own Seller.  This method
* should contain the strategy for responding to bids.
*/
protected abstract String makeResponse(int price);

/**
* @return This seller formatted as a String.  The String contains
* current details of the state of the bargaining and the history of
* bids and offers.
*/
public String toString() {
StringBuffer sb = new StringBuffer(sellerName);
sb.append(“\tcost\t”);
sb.append(cost);
sb.append(“\tDTS\t”);
sb.append(numDaysToSell);
sb.append(“\tBuyer\t”);
sb.append(getBuyerName());
switch (state) {
case DEALING:
sb.append(“\tNo deal yet\t”);
break;
case ACCEPTED:
sb.append(“\taccepted\t”);
sb.append(history.getLastBuyerBid());
sb.append(“\tprofit\t” + (history.getLastBuyerBid()-getCost()));
break;
case REJECTED:
sb.append(“\trejected\t”);
sb.append(history.getLastBuyerBid());
sb.append(“\tprofit\t-10.”);
break;
case OFFERACCEPTED:
sb.append(“\toffer accepted\t”);
sb.append(history.getLastSellerOffer());
sb.append(“\tprofit\t” + (history.getLastSellerOffer()-getCost()));
break;
case OFFERREJECTED:
sb.append(“\toffer rejected\t”);
sb.append(history.getLastSellerOffer());
sb.append(“\tprofit\t-10.”);
break;
}
sb.append(“\n\n”);
sb.append(history.toString());
return sb.toString();
}
}

TransactionHistory class:

package buyersellerprogram.bargainer;

import java.util.ArrayList;

/**
* This class models a history of bids made by a buyer and offers made
* by a seller. Methods allow you to store a bid or an offer in the
* history and later query them.
*/
public class TransactionHistory {

private ArrayList bidBuyPrices;
private ArrayList offerSellPrices;

/**
* Construct a new object of type TransactionHistory.
* It will have an empty list of bids and offers
*/
public TransactionHistory() {
bidBuyPrices = new ArrayList();
offerSellPrices = new ArrayList();
}

/**
* reset the list of bids and offers
*/
public void reset() {
bidBuyPrices.clear();
offerSellPrices.clear();
}

/**
* Record a buyer’s bid price in the history
* @param bidPrice The price of the bid
*/
public void buyerBid(int bidPrice) {
bidBuyPrices.add(new Integer(bidPrice));
}

/**
* Record a seller’s offer price in the history
* @param offerPrice The price of the offer
*/
public void sellerOffer(int offerPrice) {
offerSellPrices.add(new Integer(offerPrice));
}

/**
* Query to retrieve the nth bid from the history
* @param n The index of bit to retrieve
* @return The value of the nth bid
*/
public int getBuyerBid(int n) {
if (n = bidBuyPrices.size()) {
return -1;
} else {
return ((Integer)(bidBuyPrices.get(n))).intValue();
}
}

/**
* Query to retrieve the last bid from the history. The bid will
* have been made by a buyer.
* @return The value of the last bid
*/
public int getLastBuyerBid() {
return ((Integer)(bidBuyPrices.get(bidBuyPrices.size()-1))).intValue();
}

/**
* Query to retrieve the number of bids in the history
* @return The number of recorded bids
*/
public int getNumBidsToBuy() {
return bidBuyPrices.size();
}

/**
* Query to retrieve the last offer from the history. The offer
* will have been made by a seller.
* @return The value of the last bid
*/
public int getLastSellerOffer() {
return ((Integer)(offerSellPrices.get(offerSellPrices.size()-1))).intValue();
}

/**
* Query to get the nth offer from the history of offers. The first
* offer is offer 0, the second is offer 1, etc. Offers are made by
* a seller.
*/
public int getSellerOffer(int n) {
if (n = offerSellPrices.size()) {
return -1;
} else {
return ((Integer)(offerSellPrices.get(n))).intValue();
}
}

/**
* Query to find out how many offers have been recorded in the
* history.
* @return The number of recorded offers.
*/
public int getNumOffersToSell() {
return offerSellPrices.size();
}

/**
* Convert the history of bids and offers into a String.
* @return The history formatted as a String.
*/
public String toString() {
StringBuffer sb = new StringBuffer(“History…\n———-\nBuyer\tSeller\n”);
for (int i=0; i<bidBuyPrices.size(); i++) {
sb.append(bidBuyPrices.get(i));
if (i < offerSellPrices.size()) {
sb.append(“\t”);
sb.append(offerSellPrices.get(i));
}
sb.append(“\n”);
}
sb.append(“———————–\n”);
return sb.toString();
}
}

Applcation completed as a part of the Network Programming Module at University of East London by following group members:
Thema GUISHARD, Ian WELLS, David McCALLA and myself.

Leave a comment

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.