diff --git a/IMU/I2Cdev.h b/IMU/I2Cdev.h index 49765ad..47581df 100644 --- a/IMU/I2Cdev.h +++ b/IMU/I2Cdev.h @@ -1,4 +1,4 @@ -// I2Cdev library collection - Main I2C device class +// I2Cdev library collection - Main I2C device class header file // Abstracts bit and byte I2C R/W functions into a convenient class // 6/9/2012 by Jeff Rowberg // @@ -41,387 +41,37 @@ THE SOFTWARE. =============================================== */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "I2Cdev.h" +#ifndef _I2CDEV_H_ +#define _I2CDEV_H_ -/** Default constructor. - */ -I2Cdev::I2Cdev() { -} +#ifndef TRUE +#define TRUE (1==1) +#define FALSE (0==1) +#endif -/** Read a single bit from an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param bitNum Bit position to read (0-7) - * @param data Container for single bit value - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (true = success) - */ -int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout) { - uint8_t b; - uint8_t count = readByte(devAddr, regAddr, &b, timeout); - *data = b & (1 << bitNum); - return count; -} +class I2Cdev { + public: + I2Cdev(); + + static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout); + static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout); -/** Read a single bit from a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param bitNum Bit position to read (0-15) - * @param data Container for single bit value - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (true = success) - */ -int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout) { - uint16_t b; - uint8_t count = readWord(devAddr, regAddr, &b, timeout); - *data = b & (1 << bitNum); - return count; -} + static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data); + static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data); + static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data); + static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); + static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data); + static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); + static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data); + static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data); -/** Read multiple bits from an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param bitStart First bit position to read (0-7) - * @param length Number of bits to read (not more than 8) - * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (true = success) - */ -int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) { - // 01101001 read byte - // 76543210 bit numbers - // xxx args: bitStart=4, length=3 - // 010 masked - // -> 010 shifted - uint8_t count, b; - if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) { - uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); - b &= mask; - b >>= (bitStart - length + 1); - *data = b; - } - return count; -} - -/** Read multiple bits from a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param bitStart First bit position to read (0-15) - * @param length Number of bits to read (not more than 16) - * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (1 = success, 0 = failure, -1 = timeout) - */ -int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout) { - // 1101011001101001 read byte - // fedcba9876543210 bit numbers - // xxx args: bitStart=12, length=3 - // 010 masked - // -> 010 shifted - uint8_t count; - uint16_t w; - if ((count = readWord(devAddr, regAddr, &w, timeout)) != 0) { - uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); - w &= mask; - w >>= (bitStart - length + 1); - *data = w; - } - return count; -} - -/** Read single byte from an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param data Container for byte value read from device - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (true = success) - */ -int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout) { - return readBytes(devAddr, regAddr, 1, data, timeout); -} - -/** Read single word from a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to read from - * @param data Container for word value read from device - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Status of read operation (true = success) - */ -int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout) { - return readWords(devAddr, regAddr, 1, data, timeout); -} - -/** Read multiple bytes from an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr First register regAddr to read from - * @param length Number of bytes to read - * @param data Buffer to store read data in - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Number of bytes read (-1 indicates failure) - */ -int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout) { - int8_t count = 0; - int fd = open("/dev/i2c-1", O_RDWR); - - if (fd < 0) { - fprintf(stderr, "Failed to open device: %s\n", strerror(errno)); - return(-1); - } - if (ioctl(fd, I2C_SLAVE, devAddr) < 0) { - fprintf(stderr, "Failed to select device: %s\n", strerror(errno)); - close(fd); - return(-1); - } - if (write(fd, ®Addr, 1) != 1) { - fprintf(stderr, "Failed to write reg: %s\n", strerror(errno)); - close(fd); - return(-1); - } - count = read(fd, data, length); - if (count < 0) { - fprintf(stderr, "Failed to read device(%d): %s\n", count, ::strerror(errno)); - close(fd); - return(-1); - } else if (count != length) { - fprintf(stderr, "Short read from device, expected %d, got %d\n", length, count); - close(fd); - return(-1); - } - close(fd); - - return count; -} - -/** Read multiple words from a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr First register regAddr to read from - * @param length Number of words to read - * @param data Buffer to store read data in - * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) - * @return Number of words read (0 indicates failure) - */ -int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout) { - int8_t count = 0; - - printf("ReadWords() not implemented\n"); - // Use readBytes() and potential byteswap - *data = 0; // keep the compiler quiet - - return count; -} - -/** write a single bit in an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to write to - * @param bitNum Bit position to write (0-7) - * @param value New bit value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data) { - uint8_t b; - readByte(devAddr, regAddr, &b); - b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); - return writeByte(devAddr, regAddr, b); -} - -/** write a single bit in a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to write to - * @param bitNum Bit position to write (0-15) - * @param value New bit value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data) { - uint16_t w; - readWord(devAddr, regAddr, &w); - w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); - return writeWord(devAddr, regAddr, w); -} - -/** Write multiple bits in an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to write to - * @param bitStart First bit position to write (0-7) - * @param length Number of bits to write (not more than 8) - * @param data Right-aligned value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data) { - // 010 value to write - // 76543210 bit numbers - // xxx args: bitStart=4, length=3 - // 00011100 mask byte - // 10101111 original value (sample) - // 10100011 original & ~mask - // 10101011 masked | value - uint8_t b; - if (readByte(devAddr, regAddr, &b) != 0) { - uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); - data <<= (bitStart - length + 1); // shift data into correct position - data &= mask; // zero all non-important bits in data - b &= ~(mask); // zero all important bits in existing byte - b |= data; // combine data with existing byte - return writeByte(devAddr, regAddr, b); - } else { - return false; - } -} - -/** Write multiple bits in a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register regAddr to write to - * @param bitStart First bit position to write (0-15) - * @param length Number of bits to write (not more than 16) - * @param data Right-aligned value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data) { - // 010 value to write - // fedcba9876543210 bit numbers - // xxx args: bitStart=12, length=3 - // 0001110000000000 mask byte - // 1010111110010110 original value (sample) - // 1010001110010110 original & ~mask - // 1010101110010110 masked | value - uint16_t w; - if (readWord(devAddr, regAddr, &w) != 0) { - uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); - data <<= (bitStart - length + 1); // shift data into correct position - data &= mask; // zero all non-important bits in data - w &= ~(mask); // zero all important bits in existing word - w |= data; // combine data with existing word - return writeWord(devAddr, regAddr, w); - } else { - return false; - } -} - -/** Write single byte to an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register address to write to - * @param data New byte value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) { - return writeBytes(devAddr, regAddr, 1, &data); -} - -/** Write single word to a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr Register address to write to - * @param data New word value to write - * @return Status of operation (true = success) - */ -bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) { - return writeWords(devAddr, regAddr, 1, &data); -} - -/** Write multiple bytes to an 8-bit device register. - * @param devAddr I2C slave device address - * @param regAddr First register address to write to - * @param length Number of bytes to write - * @param data Buffer to copy new data from - * @return Status of operation (true = success) - */ -bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data) { - int8_t count = 0; - uint8_t buf[128]; - int fd; - - if (length > 127) { - fprintf(stderr, "Byte write count (%d) > 127\n", length); - return(FALSE); - } - - fd = open("/dev/i2c-1", O_RDWR); - if (fd < 0) { - fprintf(stderr, "Failed to open device: %s\n", strerror(errno)); - return(FALSE); - } - if (ioctl(fd, I2C_SLAVE, devAddr) < 0) { - fprintf(stderr, "Failed to select device: %s\n", strerror(errno)); - close(fd); - return(FALSE); - } - buf[0] = regAddr; - memcpy(buf+1,data,length); - count = write(fd, buf, length+1); - if (count < 0) { - fprintf(stderr, "Failed to write device(%d): %s\n", count, ::strerror(errno)); - close(fd); - return(FALSE); - } else if (count != length+1) { - fprintf(stderr, "Short write to device, expected %d, got %d\n", length+1, count); - close(fd); - return(FALSE); - } - close(fd); - - return TRUE; -} - -/** Write multiple words to a 16-bit device register. - * @param devAddr I2C slave device address - * @param regAddr First register address to write to - * @param length Number of words to write - * @param data Buffer to copy new data from - * @return Status of operation (true = success) - */ -bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data) { - int8_t count = 0; - uint8_t buf[128]; - int i, fd; - - // Should do potential byteswap and call writeBytes() really, but that - // messes with the callers buffer - - if (length > 63) { - fprintf(stderr, "Word write count (%d) > 63\n", length); - return(FALSE); - } - - fd = open("/dev/i2c-1", O_RDWR); - if (fd < 0) { - fprintf(stderr, "Failed to open device: %s\n", strerror(errno)); - return(FALSE); - } - if (ioctl(fd, I2C_SLAVE, devAddr) < 0) { - fprintf(stderr, "Failed to select device: %s\n", strerror(errno)); - close(fd); - return(FALSE); - } - buf[0] = regAddr; - for (i = 0; i < length; i++) { - buf[i*2+1] = data[i] >> 8; - buf[i*2+2] = data[i]; - } - count = write(fd, buf, length*2+1); - if (count < 0) { - fprintf(stderr, "Failed to write device(%d): %s\n", count, ::strerror(errno)); - close(fd); - return(FALSE); - } else if (count != length*2+1) { - fprintf(stderr, "Short write to device, expected %d, got %d\n", length+1, count); - close(fd); - return(FALSE); - } - close(fd); - return TRUE; -} - -/** Default timeout value for read operations. - * Set this to 0 to disable timeout detection. - */ -uint16_t I2Cdev::readTimeout = 0; + static uint16_t readTimeout; +}; +#endif /* _I2CDEV_H_ */ diff --git a/TCP/Makefile b/TCP/Makefile new file mode 100644 index 0000000..c0db33b --- /dev/null +++ b/TCP/Makefile @@ -0,0 +1,12 @@ +all: TCPserver.o TCPserverExample + +HDRS = TCPserver.h +CXXFLAGS = -Wall + +TCPserver.o TCPserverExample.o: $(HDRS) + +TCPserverExample: TCPserver.o TCPserverExample.o + $(CXX) $^ -o $@ + +clean: + rm TCPserver.o TCPserverExample.o TCPserverExample diff --git a/TCP/TCPclient.class b/TCP/TCPclient.class new file mode 100644 index 0000000..0fc92ed Binary files /dev/null and b/TCP/TCPclient.class differ diff --git a/TCP/TCPclient.java b/TCP/TCPclient.java new file mode 100644 index 0000000..c421b52 --- /dev/null +++ b/TCP/TCPclient.java @@ -0,0 +1,68 @@ +/** + * TCPclient.java + * Written by Brendan Haines + * Based on example from http://www.java-samples.com/showtutorial.php?tutorialid=1167 + */ + +import java.lang.*; +import java.io.*; +import java.net.*; + +class TCPclient { + /** Socket at the server */ + private Socket socket; + /** buffer to hold received info */ + private BufferedReader buffer; + + /** + * Connects to socket at server + * @param host - the server's IP + * @param port - the port number of the socket at the server + */ + public TCPclient( String host, int port ) { + try { + System.out.println( "setting up socket" ); + socket = new Socket( host, port ); + System.out.println( "socket set up\nsetting up buffer" ); + buffer = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); + System.out.println( "buffer set up" ); + } + catch( Exception e ) { + System.out.println( "ERROR -- constructor" ); + close(); + } + } + + /** + * reads one line from the receive buffer + * @return one line of the receive buffer on success, null on failure + */ + public String readLine() { + try{ + if( buffer.ready() ) { + return buffer.readLine(); + } + else { + return null; + } + } + catch( Exception e ) { + System.out.println( "Hmmm... it won't read" ); + return null; + } + } + + /** + * close connection + */ + public void close() { + try { + buffer.close(); + socket.close(); + } + catch( Exception e ) { + System.out.println( "SH*T! the connection won't close" ); + } + } +} + diff --git a/TCP/TCPclientExample.class b/TCP/TCPclientExample.class new file mode 100644 index 0000000..bc608c8 Binary files /dev/null and b/TCP/TCPclientExample.class differ diff --git a/TCP/TCPclientExample.java b/TCP/TCPclientExample.java new file mode 100644 index 0000000..06b2ef7 --- /dev/null +++ b/TCP/TCPclientExample.java @@ -0,0 +1,11 @@ +/** + * Written By Brendan Haines + */ + +class TCPclientExample { + public static void main( String args[] ) { + TCPclient client = new TCPclient( "192.168.42.1", 51719 ); + System.out.println( "Setup successful" ); + client.close(); + } +} \ No newline at end of file diff --git a/TCP/TCPserver.cpp b/TCP/TCPserver.cpp new file mode 100644 index 0000000..fdc0cea --- /dev/null +++ b/TCP/TCPserver.cpp @@ -0,0 +1,134 @@ +/* +* TCPserver.cpp +* Written by Brendan Haines +* Based heavily on example code found at http://www.linuxhowtos.org/C_C++/socket.htm +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "TCPserver.h" + +TCPserver::TCPserver() +{} + +// Constructor sets everything up and starts monitoring thread +TCPserver::TCPserver( int port ) +{ + portNumber = port; + setupSocket(); +} + +// Destructor closes sockets +TCPserver::~TCPserver() +{ + close( connectionFD ); + close( socketFD ); +} + +// a unified/consistent way of reporting errors +void TCPserver::handleError( const char* message ) +{ + perror( message ); // print message to stderror + +} + +// Returns true on success, false on failure +bool TCPserver::setupSocket() +{ + // Create a new socket + // AF_INET: internet domain (not unix domain) + // SOCK_STREAM: stream (not datagram) + // 0: lets OS decide correct protocol (TCP) + socketFD = socket( AF_INET, SOCK_STREAM, 0 ); + if( socketFD < 0 ) // error setting up socket + { + handleError( "Error setting up socket\n" ); + return false; + } + + // fill server_addr with zeroes + // NOTE: memset sets arg2 bytes following arg0 to arg1 + // NOTE: sizeof returns the size of the passed type in bytes + memset( (char*) &server_addr, 0, sizeof( server_addr ) ); + + server_addr.sin_family = AF_INET; // just following the example (and its documentation) + server_addr.sin_port = htons( portNumber ); // assign the port number. NOTE: htons converts host byte order to network byte order + server_addr.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY represents the IP address of the host + + // bind: binds the socket to an address + if( bind( socketFD, (struct sockaddr*) &server_addr, sizeof( server_addr ) ) < 0 ) + { + handleError( "Error binding socket" ); + return false; + } + + // listen for connections to socket (max 5 waiting) + listen( socketFD, 5 ); + + clientAddrLen = sizeof( client_addr ); + + // wait for client to connect + printf( "Waiting for client to connect\n" ); + connectionFD = accept( socketFD, (struct sockaddr*) &client_addr, &clientAddrLen ); + if( connectionFD < 0 ) + { + handleError( "Error on accept" ); + return false; + } + + // empty buffer + memset( buffer, 0, sizeof( buffer ) ); + + return true; // setup successful +} + +// returns a pointer to the buffer +char* TCPserver::getBuffer() +{ + return buffer; +} + +// returns the connection file descriptor +int TCPserver::getConnectionFD() +{ + return connectionFD; +} +/* +void TCPserver::startMonitoringThread() +{ + // create thread: ( thread, NULL = default values, function to run, parameter (void*) or NULL ) + if( pthread_create( &monitorThread, NULL, monitoringThread, (void*) this ) ) + { + // error creating thread + handleError( "Error creating thread" ); + return; + } +} + +void* TCPserver::monitoringThread( void* serverPointer ) +{ + int n; // contains the number of characters read + + TCPserver server; + + while( true ) + { + // read from the socket and put in the buffer + n = read( server.getConnectionFD(), server.getBuffer(), 255 ); + if( n < 0 ) + { + server.handleError( "Error reading -- monitorThread " ); + pthread_exit( NULL ); // exit this thread + } + } +} +*/ + diff --git a/TCP/TCPserver.h b/TCP/TCPserver.h new file mode 100644 index 0000000..ab85d61 --- /dev/null +++ b/TCP/TCPserver.h @@ -0,0 +1,42 @@ +/* +* TCPserver.h +* Written by Brendan Haines +* Based heavily on example code found at http://www.linuxhowtos.org/C_C++/socket.htm +*/ + +#ifndef TCP_SERVER_H +#define TCP_SERVER_H + +#include + + +class TCPserver { +public: + TCPserver(); + TCPserver( int port ); // Constructor + ~TCPserver(); // Destructor + + void handleError( const char* message ); + + char* getBuffer(); + int getConnectionFD(); + + char buffer[ 256 ]; // buffer to store read data +private: + int socketFD; // file descriptor for the socket + int connectionFD; // file descriptor for the connection + int portNumber; // port number of the socket + socklen_t clientAddrLen; // stores the length of the client's address + + struct sockaddr_in server_addr; // contains the server's address + struct sockaddr_in client_addr; // contains the client's address + + //pthread_t monitorThread; // thread to monitor the socket and read to buffer + + bool setupSocket(); + + //void startMonitoringThread(); + //void* monitoringThread( void* ); +}; + +#endif diff --git a/TCP/TCPserver.o b/TCP/TCPserver.o new file mode 100644 index 0000000..956e754 Binary files /dev/null and b/TCP/TCPserver.o differ diff --git a/TCP/TCPserverExample b/TCP/TCPserverExample new file mode 100755 index 0000000..772cdf6 Binary files /dev/null and b/TCP/TCPserverExample differ diff --git a/TCP/TCPserverExample.cpp b/TCP/TCPserverExample.cpp new file mode 100644 index 0000000..ad8d702 --- /dev/null +++ b/TCP/TCPserverExample.cpp @@ -0,0 +1,11 @@ +/* +* TCPserverExample.cpp +*/ + +#include "stdio.h" +#include "TCPserver.h" + +int main( int argc, char* argv[] ) +{ + TCPserver serv( 51719 ); +} \ No newline at end of file diff --git a/TCP/TCPserverExample.o b/TCP/TCPserverExample.o new file mode 100644 index 0000000..fc8ba31 Binary files /dev/null and b/TCP/TCPserverExample.o differ diff --git a/TCPexample/README b/TCPexample/README new file mode 100644 index 0000000..fa7f2be --- /dev/null +++ b/TCPexample/README @@ -0,0 +1,5 @@ +Example code using TCP/IP protocol with C++ +Example and documentation found at http://www.linuxhowtos.org/C_C++/socket.htm + +server.c and client.c are original files +server2.c is commented and reformatted to facilitate understanding the underlying process diff --git a/TCPexample/client b/TCPexample/client new file mode 100755 index 0000000..923b6aa Binary files /dev/null and b/TCPexample/client differ diff --git a/TCPexample/client.c b/TCPexample/client.c new file mode 100644 index 0000000..181de35 --- /dev/null +++ b/TCPexample/client.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +void error(const char *msg) +{ + perror(msg); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int sockfd, portno, n; + struct sockaddr_in serv_addr; + struct hostent *server; + + char buffer[256]; + if (argc < 3) { + fprintf(stderr,"usage %s hostname port\n", argv[0]); + exit(0); + } + portno = atoi(argv[2]); + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + server = gethostbyname(argv[1]); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + exit(0); + } + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy((char *)server->h_addr, + (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) + error("ERROR connecting"); + printf("Please enter the message: "); + bzero(buffer,256); + fgets(buffer,255,stdin); + n = write(sockfd,buffer,strlen(buffer)); + if (n < 0) + error("ERROR writing to socket"); + bzero(buffer,256); + n = read(sockfd,buffer,255); + if (n < 0) + error("ERROR reading from socket"); + printf("%s\n",buffer); + close(sockfd); + return 0; +} diff --git a/TCPexample/server b/TCPexample/server new file mode 100755 index 0000000..6d3ff87 Binary files /dev/null and b/TCPexample/server differ diff --git a/TCPexample/server.c b/TCPexample/server.c new file mode 100644 index 0000000..84ec350 --- /dev/null +++ b/TCPexample/server.c @@ -0,0 +1,55 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include +#include +#include +#include +#include +#include +#include + +void error(const char *msg) +{ + perror(msg); + exit(1); +} + +int main(int argc, char *argv[]) +{ + int sockfd, newsockfd, portno; + socklen_t clilen; + char buffer[256]; + struct sockaddr_in serv_addr, cli_addr; + int n; + if (argc < 2) { + fprintf(stderr,"ERROR, no port provided\n"); + exit(1); + } + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + bzero((char *) &serv_addr, sizeof(serv_addr)); + portno = atoi(argv[1]); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(portno); + if (bind(sockfd, (struct sockaddr *) &serv_addr, + sizeof(serv_addr)) < 0) + error("ERROR on binding"); + listen(sockfd,5); + clilen = sizeof(cli_addr); + newsockfd = accept(sockfd, + (struct sockaddr *) &cli_addr, + &clilen); + if (newsockfd < 0) + error("ERROR on accept"); + bzero(buffer,256); + n = read(newsockfd,buffer,255); + if (n < 0) error("ERROR reading from socket"); + printf("Here is the message: %s\n",buffer); + n = write(newsockfd,"I got your message",18); + if (n < 0) error("ERROR writing to socket"); + close(newsockfd); + close(sockfd); + return 0; +} diff --git a/TCPexample/server2.c b/TCPexample/server2.c new file mode 100644 index 0000000..833ea53 --- /dev/null +++ b/TCPexample/server2.c @@ -0,0 +1,127 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +// From: +// http://www.linuxhowtos.org/C_C++/socket.htm + +#include +#include +#include +#include +#include +#include +#include + +void error( const char *msg ) +{ + perror( msg ); + exit( 1 ); +} + +int main( int argc, char *argv[] ) +{ + // VARIABLE DEFINITONS + + // file descriptors + int sockfd; // returned by socket system call + int newsockfd; // returned by accept system call + + int portno; // stores port number (passed as argument) + socklen_t clilen; // stores the size of the client address. needed for the accept system call + char buffer[ 256 ]; // server reads characters from socket connection into buffer + + // sockaddr_in is defined in "netinet/in.h" + struct sockaddr_in serv_addr; // serv_addr contains the server address + struct sockaddr_in cli_addr; // cli_addr contains the client address + + int n; // return value for read/write calls (contains the # of characters read/written) + + // BEGIN REAL CODE + + // Check that there are enough arguments + if( argc < 2 ) + { + fprintf( stderr, "ERROR, no port provided\n" ); + exit( 1 ); + } + + // socket system call creates new socket + // arg0: address domain ( Unix domain [AF_UNIX] or Internet domain [AF_INET] ) + // arg1: socket type ( Stream [SOCK_STREAM] or Datagram [SOCK_DGRAM] ) + // arg2: protocol ( 0 lets system decide best protocol: TCP for streams, UDP for datagrams ) + // returns file descriptor on success + // returns -1 on failure + sockfd = socket( AF_INET, SOCK_STREAM, 0 ); + if( sockfd < 0 ) // on error: sockfd = -1 + error( "ERROR opening socket" ); + + // bzero sets all values in a buffer to zero + // arg0: pointer to buffer + // arg1: length of buffer + bzero( (char*) &serv_addr, sizeof( serv_addr ) ); // initializes serv_addr to all zeroes + + // atoi converts a string of digits to an integer + portno = atoi( argv[ 1 ] ); + + serv_addr.sin_family = AF_INET; // sin_family should always be set to symbolic constant AF_INET + serv_addr.sin_addr.s_addr = INADDR_ANY; // sin_addr.s_addr contains the IP address of the host. INADDR_ANY is a symbolic constant which get this address + serv_addr.sin_port = htons( portno ); // sin_port contains the port number. htons converts a port number in host byte order to network byte order + + // bind system call binds a socket to an address ( address = address of host & port number) + // arg0: socket file descriptor + // arg1: pointer to structure of type sockaddr. what is passed is a structure of type sockaddr_in, must be cast to correct type + // arg2: size of structure &arg1 + // returns 0 on success ????????? + if( bind( sockfd, ( struct sockaddr* ) &serv_addr, sizeof( serv_addr ) ) < 0 ) + error( "ERROR on binding" ); + + // listen system call allows program to listen to socket for connections + // arg0: file descriptor of socket + // arg1: size of backlog queue (maximum number of connections which can be waiting while handling any specific connection) (standard: 5) + listen( sockfd, 5 ); + + // set client address length to the size of client's address + clilen = sizeof( cli_addr ); + + // accept system call causes the program to stop until a client connects to the server + // arg0: file descriptor of the socket + // arg1: pointer for the client address structure + // arg2: size of structure &arg1 + // returns a file descriptor for the connection on success + // returns -1 on failure ????? + newsockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen ); + if( newsockfd < 0 ) + error( "ERROR on accept" ); + + bzero( buffer, 256 ); // clear the receive buffer + + // read system call reads from socket + // read will block the program until there is something to read + // arg0: file descriptor for the connection (NOTE: this is the new one returned by accept) + // arg1: buffer to put characters into + // arg2: maximum number of character to read and put in buffer + // return number of characters read on success + // return -1 on failure ????? + n = read( newsockfd, buffer, 255 ); + if ( n < 0 ) + error("ERROR reading from socket"); + + // buffer will contain the message now + printf( "Here is the message: %s\n", buffer ); + + // write system call writes to socket + // arg0: file descriptor for the connection (NOTE: again, this is the new one returned by accept) + // arg1: pointer to character (char*) + // arg2: length of &arg1 + // return number of characters written on success + // return -1 on failure + n = write( newsockfd, "I got your message", 18 ); + if ( n < 0 ) + error( "ERROR writing to socket" ); + + // when socket is no longer needed, close the connection + close( newsockfd ); + close( sockfd ); + + return 0; +}