From 7b862ad27073c3333bf4397da58551bf10489cfd Mon Sep 17 00:00:00 2001 From: Brendan Date: Fri, 9 Jan 2015 13:21:07 -0700 Subject: [PATCH] Adds TCP/IP stuff --- IMU/I2Cdev.h | 410 +++---------------------------------- TCP/Makefile | 12 ++ TCP/TCPclient.class | Bin 0 -> 1372 bytes TCP/TCPclient.java | 68 ++++++ TCP/TCPclientExample.class | Bin 0 -> 557 bytes TCP/TCPclientExample.java | 11 + TCP/TCPserver.cpp | 134 ++++++++++++ TCP/TCPserver.h | 42 ++++ TCP/TCPserver.o | Bin 0 -> 3708 bytes TCP/TCPserverExample | Bin 0 -> 9556 bytes TCP/TCPserverExample.cpp | 11 + TCP/TCPserverExample.o | Bin 0 -> 920 bytes TCPexample/README | 5 + TCPexample/client | Bin 0 -> 9388 bytes TCPexample/client.c | 57 ++++++ TCPexample/server | Bin 0 -> 9240 bytes TCPexample/server.c | 55 +++++ TCPexample/server2.c | 127 ++++++++++++ 18 files changed, 552 insertions(+), 380 deletions(-) create mode 100644 TCP/Makefile create mode 100644 TCP/TCPclient.class create mode 100644 TCP/TCPclient.java create mode 100644 TCP/TCPclientExample.class create mode 100644 TCP/TCPclientExample.java create mode 100644 TCP/TCPserver.cpp create mode 100644 TCP/TCPserver.h create mode 100644 TCP/TCPserver.o create mode 100755 TCP/TCPserverExample create mode 100644 TCP/TCPserverExample.cpp create mode 100644 TCP/TCPserverExample.o create mode 100644 TCPexample/README create mode 100755 TCPexample/client create mode 100644 TCPexample/client.c create mode 100755 TCPexample/server create mode 100644 TCPexample/server.c create mode 100644 TCPexample/server2.c 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 0000000000000000000000000000000000000000..0fc92ed3b857a40b862bec58e1f5fa689a2a3efd GIT binary patch literal 1372 zcmZux=~5Fx80-PUZk9E21rZMxPY9BDU!X!T2+EmIR$=)kECa44yQyU2@hColf6)@C z(kdUohf;fX6Xmc{wKLn_(LFui=I5_(KLA|Es)YfJ#gRtF#8nH|aNWQS3o+b`<0NjG zxNYE$fx8;IXTidK3vrC=;Dm_>1|FJtWbtiM<5T*PH8HJMA~8&wcx)hNU`C+57PxPu z66l(LU3^>2_)=vGAvDh5dVOOvbZ6uI%mT3J@rtaZ#YUS75%MD zK~+6}YkY3xxj@@=uptGG&wIXHte4kib+x!&B66&titd|*VkLYJ6+NMN0kg{PI$fZ5 zc;skXftXtgY7DmyYX++j)T^$X@pRY3>h!W(@}#fQ`b0JckuorAV-8Pw%$ih+(wut5 ziH>gInT>fYP~jm5bg5(G6iy2aM#&D#S!(U;()6e=tUh9qz{zG{&ac!Josq?IWS@;i zENPZy{aCSa24`tY)UiP&&=b~&w&vcuvZB1er!l#Fekt#ajX7@M*HpFcs-S9P1SuPN z6l`3^ut0LQTrQ{6X~$E}yTHG!9Br+DQ?9|b!9NmyEc z&FlkEblC@?4>cvryq}=X+~nW!S>{+YEa2=!C!=NiU;(3|lS({e@;@V`?>n(2)jl%? zPBf>4z4ir2(cfrsD4@Ia{0l|bF|N^=Ht0h*Suf!5BO2gG*}@;kAl&hexVC~b!MMN> z-*(WBHm-%#9>f>4bhqxJE%hC-wb9diXy1XMK{Ep5Yu{n5rM|-0MaLfOJsjIXLMI$& z!Y6bt>V20^-bMFkQnVq996BlD97)pX;IoftKWqxr5{D@7J_TmE%TeGA#Vt}^o)zbr z-HVpr473`!VBn&FFmTCcXAVi@2(Q9J0)rHm*hSArbVR$}ZLvMC6(y-iY%>k$V#7{! zqbFP=Sp)O{Nb&Dzl#w(e*O27j*%{mjB^YcmMOyN4NE@s#8?2`yuD-~X6Q5v*l>MaC l1^@|iHVufFCSc$J@hL_gk#UkXWSdMYBr;hz%F-5G`2(4}CcFRu literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..bc608c8b2b6929011cf95287284312973781608e GIT binary patch literal 557 zcmZuu+e*Vg5Ix(b-Lyun(P+I?>%A(pC?blNm!cpPEu;wIQyN!^pj3lP!7x~Jd~p(cP0?;xO_vbGvmBpcv~*Fsv2Lx3Yx&m|Gip2j z^{y0V%^+^u;>eL?qfxEft|R>D@XqpDt|&{51`YiTneR&mZGC5>yuP(v-lQP!iyX5W z<}lBYGes1)ieYTqA`Gu$mt#T0B9=5P%R0I5I$tIP^;$b^-UvIA4gc-;ST_8FYu<;E z@Mr`>HngkdI zC@WB86jQ6uU=Nhg^yy4@L1d7_5ap7(52Yg>e?{V4PwL7uQng2 +#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 0000000000000000000000000000000000000000..956e754cbe8584736491894f3114bfa1f50e0444 GIT binary patch literal 3708 zcmb7HQD_`h6n%+lyQ#Ii)hHE>nQEY-Y{^DjXt9_y8JS|D)wHyVVX|&#o5f^z*_~~J z5ZtAuW?WMui1;P_kXEE0{n4aBLSiKO5i9s3e&wU;3RPAbq^**A?t6FAWM&fRC9`+$ zJ?Gwc-+gc1+g!c<=h7x2YVH&Gz(cx9UohwO|z?W8N`<%uB(rGF@k*L>aQ2#enniB(lo7pGntDIS_<^m z_cJ%^Jqi0ncN2(7Jn;BZl*< z;SAsGolSuIc)7PS6% z*H;xFcR^Chu5i;CSpn}C&D}5M_o+5m)#WAVuBzEN`gNJd!79lS!%c1XwBHP;AUDm5 zYQ|{%q;oUr=u6@8;iZ}1L*eo6rI}ly`m1n<$EPtd$m)9K-qvZ)%lOr`_s;6MTqdXG zE!)OF#NIuOU9XMft@uO8f9W#=lgE4|mV+9c#q5@#*%$8hDZMwdy<1 zIBi3SZ~SS->1+$atBh}519uNkI{P5L{OlJs@4hZ-h9WhQEt^7PU^RpMIG)hIccgIt z@yc(FoUQG6fUh^n!*M98w-t})8OR#|ufjZDk3inXEAsKW1oFNCZ|FZYF0W4@?;3bT z=J7fO^5`J>lzHpT<9YDLn8)iDnC~s{MwrLz7sxxaA|J0~Any`*?tI;K^RCBN*bkZz z(T|{UCqy&QjnKWUcS1h|dl9)%dz9{3+>OzB=sHj@Kx6LF_n>z`pMb{w+t>&F1ndrI z;_ri|luturpG5ybkMTA73pC}u3{AX?(2&Nn_;?a_H#Dy5=nm+Iq1zCIzl|DeGRR&4 zPI{X4dDcbNeXQG9YpkJU+#VFS6_5LSXFu6U=)O;{F&@R_NZw%k0NZi4<7}tMMuXhn zCwaD8_(kYLjxh4O?=$r^41S35eT);2WRUTG{{2-?HXiqV-G=-WU*!0|01@uK?>9L9 z7~>Zhch9SHjE`}C+AkFEo|o;6Z)bcbArBd${9J-pZY{ zaviPuNv|vBceUy%4=WbKeOSo$$eWM?`1V_!J{Iebr;iU<@}kray_^u{pf!j{VbZNB z%z;$iw$j4P;-|cw6eeGatFv^(e8YFjx)TGLyyYpZQ)drw&QfkHBA<$N=Y z?FQDN?&wq|{ZgloL7m!V^?OpHv>-3~<>z`@<|oiR{a%`CfH!bpU%&l&-QjCCvP=Y(#ke}7tnq9~^j{{x?=)CK?m literal 0 HcmV?d00001 diff --git a/TCP/TCPserverExample b/TCP/TCPserverExample new file mode 100755 index 0000000000000000000000000000000000000000..772cdf6ca734665aed75540d4d6456a96769afa5 GIT binary patch literal 9556 zcmeHNZ)_Y#6`yr%;s!T&2~BHSsw|;Ffk=tZYJ($G)lR%{rg3X(M{R?w)%m<5UMH!C;~oFB#ablry@~8BF93gjViuW{iBFKWh151A&PK=u=)LF zXYJc{3=$vsv`;rP@Au}-n>TM}=k{jqjoTlrY!yP=B1E}K2(bgH)*{3ip@S3RlSpwS z(;VpevT?$A>Pbrdr1{|;5$)_l2c|h>JTv51k?o^?nNS$M3AiIZrm9V|XiXQ_b%XZm z+b|eZe;WfL5jVT6n>UMcBQ(uIu{2Ux69w&+x4ZTZDGd*M4O*4Gb^mD39Jex)Rvt=0 zdkf0mbIJfQ9M{i9yfaXyk|@g#0{7<#D@w*J2I{k z39$!L-a%e>$I^?gnIO}+h(fBmrI zA;=IqOeQvhZQI1>Jxm#BAI8geQFhQk?1yn+oxA?0!D;J#qyOao{Rd(P;6!>v`qkyr zzkqGWuRnOYP_!lv98pc6EyQP$=-(y8kLBkSz79;1KjxwY$0$~Kg2!s*%-y(24 zZvQ!M&nypLNkw+|3L)|Hx1yBAt24{a+pDXq@#n8bhp%j?w@V*VrCR#Xo^REJaPTf8 zUNrvZs{8Ee3;fc!2qp0v9fkQi+SXAz_BH1azRKg(e#frhD?(JxGbcr6<@fmPBQHpW z8OOPWnnhz(+39>H#1 z3r;V+n0@r`(wTneTBQxzbl5ijG$))dD0x*5IbOM}qdHza?!+sQM>VJ zhOly;Icd$AbJ7mt^E*hTGrPg4_;}Hj@j+x>MQiA2-!fJo(ju>3!hGp>n*a6rby`-u zRgjW&AhP?Lbii9Ly0>1cFVHtmFFNWWTkWsAqqB`$&Ou0Q%#!Revb)=BzrNmH*?hgl z?UGzH&OgzyyU1!>uPJ*uWg9Dz`I(i=e`$@(_pe<3sP(QlAdbvm!oWa&f92XXxaMVh zzwg6WY7Hcxhsv!1j%4=C62fqP>u))#U4M{++ZnfyFWVQcGCuaN7G!bFe%(1oZuSBj zIPDx#wdI$xfrx+6SdN_G>(v4S7_VHV@!=~Da#35|`(2c)d%q|1mt_93%)c-5AISVi zGCwQxA0x*aoqezmOwZuz-oq$s;}qU}A3cxrmF?y`QM}R*c}s6f0b*csh}mdMUI? zX3|!+s26j3GMCL-$+b4Qte!|Ftx5c#;9x$5L~1OtzU6P%hfy-|cPEKF9z?uvYIv+< zC@9wMVGh#1{*=(Bqgu3WYikYFo5@}6&GRMnN9%8@@*P#augbbAZ>zFd{m$F2%63(5 z-a}XuMj(tp7=bVXVFbbmgb@fM5Jn)3Kp25A0$~Kg2>ibyuwzgAv+QeUx5=yUMDnDW z96xD}l@j?;@zs2^*3C;cc}Z^ar~{YUWe2AslC+x0w+C9L66uV9T!&m8ascfEVsqAX zfKO&}1&g2yAd|+uSeB?8Xu_JnVGB_l2)F1sejyql!cBNFMf41iI&!JWSZOByC(vYy z9TSOkR(zm|ripRWnzoXqqJ``D1U-NF#1n^yjt&&8{1i|Z&saqBQ85@3GreL_J3M9; zkCaj=D{oARKf*$%A%B@d5`fya~LJs7%9L*@Hns1rKB*J8-u zf_(0N$m`5%4xcy!mPh?pwhli51c2Gp&cAz<2 z#8L?7MFdPuVgAp7cmS8QtRGUiuIi^0zM=4U6z0V)^?&MN)qY-KU16LhO8egbG~QKs zQnjxu+@bIm7>#J|i8t-vCoztc)w$Dy!1%0<2w)6L@Y;YQ;(u*+B7Fjh=XAXH=6u|T1nR~R<$d{o)7SBDf)mGLo#vB+gQpUc zec58{P?55R)gFrl*IlsQzfJ?ScUaqg4d1iluR0nt(gANEnhJ_KH)`==@Z0L$*s#~t r+W54aawqU@YjSh)N!*Rj+o{|=O6^YGzU1vl-d^PGLf-zfVT1fP4fb~` literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fc8ba319a35c25882325db87c065a2b15ba347d5 GIT binary patch literal 920 zcmb7CO-mb56un7pQqaaA3bnX!(QQhyvlJnc3_NI&K_V1Oc?@yVgfvl-sKJ#k6owGU zPw29LppY&CfYor?w0r5o^qiSDm;}1$fjj4ZoOkEWyL0vD_kCO>@<{N2kw4Q} zh5?JP6~_O-waK3uO&Fu6(AbaAy5+W8fgi*L>s{d?4!s@Yu-_E?UR2~Ub5n9e3ZZpz zr?%@9TY9g4P^oWg{Wc%g$h#(3Hk?Ku&e8{)QQlta*uxXRtFkyoWSiP62dc!wAknqn5Mrd;b@k%DYj=zijkT-IE{p!{N91CH&3; zJE_i`@;2|h!37G+``Y*EyZ7_fuXYDK5cnPcmQ_d8YwK?IBmqI+7ad=)`G<2~#*7cM zCyqacc@sqrHzd+dMv^n}Cq1ZMAio5&hXKMp%UU9N8qGb8nR8VzCP}>kBe%+>;$BiK zVBAsaxygfgcd_^21PbAPIMD3KR2z&@{{kj>exxj^i8wnEb9bY9(KV-1$M3A0EvH!3 z#d1}D+;bY+NNugZD&*{@+t_y-xr|krNaZuu{`kR?Q~4A$eCd|OQo#?H#w+D7u}*+B literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..923b6aa88cb86ab3f8ad440ea7ed6beb97e67c31 GIT binary patch literal 9388 zcmeHNe{38_6`o5P;<%ybKng`rv4k3#wu+OAMi$`8Ev_w@bhe#KaG&C)(2)|TSqCy5iyQzu<0wlKro9~;Q zz1(e@_7DC-+R@Ft_sx6rX6DVjy}g;c_{LvXHwqD3FT~tBAw(DQ#0DX%LIWqn`;c{H z!x$a>Ok#gxY!7SOQ>-1nDWaVobYK|ciGAbkDzZI0ZcPefYy!g(?@%(su+55nSut#H zpc9jU_)$!ViTE0y^~-C-Tq`t;l3kuGHLJq*{`^kg-h|Q!aL}Mb*}FVG+A}g{u4r0N z3fmjH&bN1586c+Lo9T-2rAoGy%}*0;+KYDW{k9zoG}C3Zf{xHyFoP~R!h@rrpa@k^kD%FV`y-EuvslP zX4^gq_Djn?q20i?VdQg0X?A9^kTZ(5bya(T8E*WbEqmp9Hf7)qW4h3??XIxb1!aye zm?v@A-n$?Vl40bMZ#BLiWp7S3Aa1qCxVSzr26{P8M~3gdD={=2#F*xft2r59rXQ=I zpdIN~Su4agJO_4=*M#T*=>Q!C4bnbMh`#~oAHq6;a&K_X3&5l&J}krv=(Wf}JKAUF z_}T4N9Bfw0zAX83E+fj-<5P2Z-!2hcUKBqf>(eHn)OLq>h=Ri>f5zE(d-{obC$UNvvF`zO=fwMn$LbA~@Yy{1wQ&1pKCm z*KR|p*KXg92QS(lkZt>Pw@N+T?K&>Jk)SiDdIFW+4&bIjrOWG}oR9C*=wF;d7EbjU zYVLx>sXi}zWJyuH#;3ks>;DIY-nKRNqB^T|crU|_?o>}gS)Xr^$Tn4cgK(6;lU;8( zF9+L)u^orLbc9nq4rTAVY+p-wr`b$DCBKx&IcIg}A`JhKO5cLg(}_##(6Q{u9k@Yv zIcG}s4KR-R)ubqO&sN=e+PeiUhFm$Rbiz417+-qbdj+$V9q6^)UVLdK?ckGm)opO5 zy7NnK9UAp>9L*`;%qjO$T^06J}JM^Aslv|)t$xy z1S8HxXYu=BoEJu%b58XbtvR(ii1!n@{xz!U?iSr`u-28@-aKW#ZGVJL<3ZV!UYV0z ztpeg5fuifn+(p*t&N*)umCgmHaUOVHmTmL;8Yba={y)$?CD)77sZ}`-e;s}r%tLoB z=*~k$Y4sQAI0MdGfx7aVyT}^dl`7ufA$W^kHTL?)e?!04za6|@TV$7T>XS{2PIZc1 ze3>J1Z-0PV?k@ckQt-ow@I+`darLu)fwkAj>;tIV8(Z%Tkx+XJt7e%e!ScD$6lh zj?401S?-hNep!AIRC&O2qOD~bTiQI3TdQ{;Y4Za=wYa--nN zrR21!b(geEp=9Ur(?u&5EW1-A#>V!HX@#Ph$L}qzR7f2(ZNKtXEnm<|4DXj%1wX}tckS3$#zd^r73&x@<8N)$ODlFA`e6!h&*sL4{X`iGr^3Kr2^jIi1M2qBMTD612w!y3S2653YI%u~8R$WtBmffO_FKZW(i zOa=orQ)S!4e*lv7N{`>!tux7NUhL%g&3bWWD~e^F&79e)E%UDVjX!M0`L?_oZ9AQz z{&lE1qyC4$wTj35!(%G)SS=1F_}>HX7m0bFNjVSOK*`GVDU_}F-VjcP@WBw~ab;`! zN(g^FgpY*q(GY$pgdYjv$3vJ$e69UALipz){9FkCHiUm4!hZ^3p1AWKcM~$Nh_6NF zEdh_+a5N?GcLsT%y9Jc@`|n2Px?Yd`9_05TBMoqIxz4 +#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 0000000000000000000000000000000000000000..6d3ff87995fcf059a584eb519d5280d0f6492cec GIT binary patch literal 9240 zcmeHNZHQD=7(SC)>t@bsDMm$CbInTp!eX(MwOqQ3mfLD2L7irI@3@2W#huyQjilM? zLbqvPpbvsVgbK<&uuxXTHKlT;A|?6}5@ONE2nIq0YtT;5bMCo1b2r2K)1Q0rocDd+ z^PcCt^WJluJLl}tKYkgzOo+$?AqtlWA(~Jhog{=K3}`}JjcTGw*|F;Gwujm}*U?&E zBK7cZ5qaig0x37NZQM}rqQ-OL+M+RH69`9Ks{5qOTmAX-j^p?)$A>}pulz79z!N>q zYbT0AEtE2s@9WB)GX?p6yTar1L-w&hph5GUkB@w^*GgtB8%{w!bE?PpnkFFjLsh16 z@pb3&b|Sq=`v>`c(0uRde&X6v$Bhmt`_fwy=^mL#$1@7oKaUrqUVMD!EW|+$ug7bp zw0dRSj-@Og*Ylm!e6#c*Vyv|b7Os;PJU}T|uiCJx#trMCZk_n+rDmOw*XNcpos_wO zR97Y`vw8c1d_D~qzCV_;@_E*#Qp!!4nq@bRuL z;#xlLi|MMzYtHY}we9z=X>Z6`WVS;)`I_&Mz~)C-k^2*CK8PCg6Tr=TwC z%h`*PiLOOG1IZp>mTOQM$D20}PHi7p`L( z^KzWQfNKipX+dS5xBiC_dgT1vn1B61E^nn4-nkHQB)Yu8^B_21$80ZuH)*^PnB^8! z_7jskEMW%141^g7Gw}ap;C|En(R})Jlj&|9HH%wED>Lvd^-%=DRQL*6R{evg3$U2Q zNhk0fU>1exwvCQBUyN0&4B8z&0?l-HAA}fGfZrI=624o6S-N#A7%_H-8r!l{RJNmA zP2oCkVMygUVh%aLdH11uKCZK0F|wsGTH?2oSz56gjFmg9)#?G7&3)<%PIWma;cL1h z6%%}B(P2ntvA>~m6|n2<0zB+|hxU>Y=LZOmFDi4~Jro@}TiK5g6yMsC;))KPiM#mc zd=Ky9Fhg1E92w-p?GE~Za0LFIjPAK>e{=c(At(n~vGHcO>r5F-u&1NK}@_efkWjI`)3Dcfe}yQyu6uOU@Y>ycF!kSF3KQ(9P0rPKihOy9(gexis$c-^08q zT<3Yt`6E33f%;F(TzL}I-k?eW?p{V*=UI-=aE9U)NzPE5Y~Fs)sOvm~j;O;|p*^U= z9Q=gq^5Kswe5;8^uU{<$*K6Dzjk|4Q(V?wlhkkB|4&5_$=xoE}qcBH@4nF*Gx!ODr ztkq`z9;-Irtl9;tU8vf{s$HtuWvabRwJoY$uG%|PyHd5SXxEmm+lyFMt*zA=*oiz@@)@54K_h?ST2z)=i8QMh>tztE{4L5to$uCDFtW+t2p)~N ziVi4|$2&!&zbVo*<+6q{C%DM65vz^vU0No!d`!!Nmd|PVqL$mVd`rs@wcM}eVJ(ko zd0fkj3@daCGZ1DV%s`ldFau!*!VH8N2s037Ak09RfiMGM2L43`rp+-Pq5HH}$*b^K z_h#AMyIF4Pi`hNmKD(*x*?TP8&Wds?Z`{<4x#Z~xZnz64aloQVgr_mWHUdoXSRyIP z!k!PiK0pClOq9+? zS*aXOZ-9D%aQSX$Y@#gDxpDnKJh@>{Ap)QeeE^>&oiRXLN3sSK}S}ft2%mh)GiDvsu=!KcaP9A{%abgMuk6-FeTj)O(mSg(w3V0G4 zjj;6`=PHZ__mLdP`@$#`-cJ%QL4~BM%3Ww{@dE)I3*bZm^O&)Ad|v=R5x_irtMxAi z@CyO_Y5>0;!0!a`2La4OyxRE=1~3lQ1@EvMP$#3}mRH?9^Q4@|V>nh4_>%*5=gNC$ zp4DE7s?Wt*`H*MY*IQzmcE p`J2YuF5X7bTg2NO=eC8vA^ff2Zvub$dkf!R@p`F`+tA1b%U{NvN2>q; literal 0 HcmV?d00001 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; +}