- •1. INTEGRATED AND AUTOMATED MANUFACTURING
- •1.1 INTRODUCTION
- •1.1.1 Why Integrate?
- •1.1.2 Why Automate?
- •1.2 THE BIG PICTURE
- •1.2.2 The Architecture of Integration
- •1.2.3 General Concepts
- •1.3 PRACTICE PROBLEMS
- •2. AN INTRODUCTION TO LINUX/UNIX
- •2.1 OVERVIEW
- •2.1.1 What is it?
- •2.1.2 A (Brief) History
- •2.1.3 Hardware required and supported
- •2.1.4 Applications and uses
- •2.1.5 Advantages and Disadvantages
- •2.1.6 Getting It
- •2.1.7 Distributions
- •2.1.8 Installing
- •2.2 USING LINUX
- •2.2.1 Some Terminology
- •2.2.2 File and directories
- •2.2.3 User accounts and root
- •2.2.4 Processes
- •2.3 NETWORKING
- •2.3.1 Security
- •2.4 INTERMEDIATE CONCEPTS
- •2.4.1 Shells
- •2.4.2 X-Windows
- •2.4.3 Configuring
- •2.4.4 Desktop Tools
- •2.5 LABORATORY - A LINUX SERVER
- •2.6 TUTORIAL - INSTALLING LINUX
- •2.7 TUTORIAL - USING LINUX
- •2.8 REFERENCES
- •3. AN INTRODUCTION TO C/C++ PROGRAMMING
- •3.1 INTRODUCTION
- •3.2 PROGRAM PARTS
- •3.3 CLASSES AND OVERLOADING
- •3.4 HOW A ‘C’ COMPILER WORKS
- •3.5 STRUCTURED ‘C’ CODE
- •3.6 COMPILING C PROGRAMS IN LINUX
- •3.6.1 Makefiles
- •3.7 ARCHITECTURE OF ‘C’ PROGRAMS (TOP-DOWN)
- •3.8 CREATING TOP DOWN PROGRAMS
- •3.9 CASE STUDY - THE BEAMCAD PROGRAM
- •3.9.1 Objectives:
- •3.9.2 Problem Definition:
- •3.9.3 User Interface:
- •3.9.3.1 - Screen Layout (also see figure):
- •3.9.3.2 - Input:
- •3.9.3.3 - Output:
- •3.9.3.4 - Help:
- •3.9.3.5 - Error Checking:
- •3.9.3.6 - Miscellaneous:
- •3.9.4 Flow Program:
- •3.9.5 Expand Program:
- •3.9.6 Testing and Debugging:
- •3.9.7 Documentation
- •3.9.7.1 - Users Manual:
- •3.9.7.2 - Programmers Manual:
- •3.9.8 Listing of BeamCAD Program.
- •3.10 PRACTICE PROBLEMS
- •3.11 LABORATORY - C PROGRAMMING
- •4. NETWORK COMMUNICATION
- •4.1 INTRODUCTION
- •4.2 NETWORKS
- •4.2.1 Topology
- •4.2.2 OSI Network Model
- •4.2.3 Networking Hardware
- •4.2.4 Control Network Issues
- •4.2.5 Ethernet
- •4.2.6 SLIP and PPP
- •4.3 INTERNET
- •4.3.1 Computer Addresses
- •4.3.2 Computer Ports
- •4.3.2.1 - Mail Transfer Protocols
- •4.3.2.2 - FTP - File Transfer Protocol
- •4.3.2.3 - HTTP - Hypertext Transfer Protocol
- •4.3.3 Security
- •4.3.3.1 - Firewalls and IP Masquerading
- •4.4 FORMATS
- •4.4.1 HTML
- •4.4.2 URLs
- •4.4.3 Encryption
- •4.4.4 Clients and Servers
- •4.4.5 Java
- •4.4.6 Javascript
- •4.5 NETWORKING IN LINUX
- •4.5.1 Network Programming in Linux
- •4.6 DESIGN CASES
- •4.7 SUMMARY
- •4.8 PRACTICE PROBLEMS
- •4.9 LABORATORY - NETWORKING
- •4.9.1 Prelab
- •4.9.2 Laboratory
- •5. DATABASES
- •5.1 SQL AND RELATIONAL DATABASES
- •5.2 DATABASE ISSUES
- •5.3 LABORATORY - SQL FOR DATABASE INTEGRATION
- •5.4 LABORATORY - USING C FOR DATABASE CALLS
- •6. COMMUNICATIONS
- •6.1 SERIAL COMMUNICATIONS
- •6.2 SERIAL COMMUNICATIONS UNDER LINUX
- •6.3 PARALLEL COMMUNICATIONS
- •6.4 LABORATORY - SERIAL INTERFACING AND PROGRAMMING
- •6.5 LABORATORY - STEPPER MOTOR CONTROLLER
- •7. PROGRAMMABLE LOGIC CONTROLLERS (PLCs)
- •7.1 BASIC LADDER LOGIC
- •7.2 WHAT DOES LADDER LOGIC DO?
- •7.2.1 Connecting A PLC To A Process
- •7.2.2 PLC Operation
- •7.3 LADDER LOGIC
- •7.3.1 Relay Terminology
- •7.3.2 Ladder Logic Inputs
- •7.3.3 Ladder Logic Outputs
- •7.4 LADDER DIAGRAMS
- •7.4.1 Ladder Logic Design
- •7.4.2 A More Complicated Example of Design
- •7.5 TIMERS/COUNTERS/LATCHES
- •7.6 LATCHES
- •7.7 TIMERS
- •7.8 COUNTERS
- •7.9 DESIGN AND SAFETY
- •7.9.1 FLOW CHARTS
- •7.10 SAFETY
- •7.10.1 Grounding
- •7.10.2 Programming/Wiring
- •7.10.3 PLC Safety Rules
- •7.10.4 Troubleshooting
- •7.11 DESIGN CASES
- •7.11.1 DEADMAN SWITCH
- •7.11.2 CONVEYOR
- •7.11.3 ACCEPT/REJECT SORTING
- •7.11.4 SHEAR PRESS
- •7.12 ADDRESSING
- •7.12.1 Data Files
- •7.12.1.1 - Inputs and Outputs
- •7.12.1.2 - User Numerical Memory
- •7.12.1.3 - Timer Counter Memory
- •7.12.1.4 - PLC Status Bits (for PLC-5s)
- •7.12.1.5 - User Function Memory
- •7.13 INSTRUCTION TYPES
- •7.13.1 Program Control Structures
- •7.13.2 Branching and Looping
- •7.13.2.1 - Immediate I/O Instructions
- •7.13.2.2 - Fault Detection and Interrupts
- •7.13.3 Basic Data Handling
- •7.13.3.1 - Move Functions
- •7.14 MATH FUNCTIONS
- •7.15 LOGICAL FUNCTIONS
- •7.15.1 Comparison of Values
- •7.16 BINARY FUNCTIONS
- •7.17 ADVANCED DATA HANDLING
- •7.17.1 Multiple Data Value Functions
- •7.17.2 Block Transfer Functions
- •7.18 COMPLEX FUNCTIONS
- •7.18.1 Shift Registers
- •7.18.2 Stacks
- •7.18.3 Sequencers
- •7.19 ASCII FUNCTIONS
- •7.20 DESIGN TECHNIQUES
- •7.20.1 State Diagrams
- •7.21 DESIGN CASES
- •7.21.1 If-Then
- •7.21.2 For-Next
- •7.21.3 Conveyor
- •7.22 IMPLEMENTATION
- •7.23 PLC WIRING
- •7.23.1 SWITCHED INPUTS AND OUTPUTS
- •7.23.1.1 - Input Modules
- •7.23.1.2 - Actuators
- •7.23.1.3 - Output Modules
- •7.24 THE PLC ENVIRONMENT
- •7.24.1 Electrical Wiring Diagrams
- •7.24.2 Wiring
- •7.24.3 Shielding and Grounding
- •7.24.4 PLC Environment
- •7.24.5 SPECIAL I/O MODULES
- •7.25 PRACTICE PROBLEMS
- •7.26 REFERENCES
- •7.27 LABORATORY - SERIAL INTERFACING TO A PLC
- •8. PLCS AND NETWORKING
- •8.1 OPEN NETWORK TYPES
- •8.1.1 Devicenet
- •8.1.2 CANbus
- •8.1.3 Controlnet
- •8.1.4 Profibus
- •8.2 PROPRIETARY NETWORKS
- •8.2.0.1 - Data Highway
- •8.3 PRACTICE PROBLEMS
- •8.4 LABORATORY - DEVICENET
- •8.5 TUTORIAL - SOFTPLC AND DEVICENET
- •9. INDUSTRIAL ROBOTICS
- •9.1 INTRODUCTION
- •9.1.1 Basic Terms
- •9.1.2 Positioning Concepts
- •9.1.2.1 - Accuracy and Repeatability
- •9.1.2.2 - Control Resolution
- •9.1.2.3 - Payload
- •9.2 ROBOT TYPES
- •9.2.1 Basic Robotic Systems
- •9.2.2 Types of Robots
- •9.2.2.1 - Robotic Arms
- •9.2.2.2 - Autonomous/Mobile Robots
- •9.2.2.2.1 - Automatic Guided Vehicles (AGVs)
- •9.3 MECHANISMS
- •9.4 ACTUATORS
- •9.5 A COMMERCIAL ROBOT
- •9.5.1 Mitsubishi RV-M1 Manipulator
- •9.5.2 Movemaster Programs
- •9.5.2.0.1 - Language Examples
- •9.5.3 Command Summary
- •9.6 PRACTICE PROBLEMS
- •9.7 LABORATORY - MITSUBISHI RV-M1 ROBOT
- •9.8 TUTORIAL - MITSUBISHI RV-M1
- •10. OTHER INDUSTRIAL ROBOTS
- •10.1 SEIKO RT 3000 MANIPULATOR
- •10.1.1 DARL Programs
- •10.1.1.1 - Language Examples
- •10.1.1.2 - Commands Summary
- •10.2 IBM 7535 MANIPULATOR
- •10.2.1 AML Programs
- •10.3 ASEA IRB-1000
- •10.4 UNIMATION PUMA (360, 550, 560 SERIES)
- •10.5 PRACTICE PROBLEMS
- •10.6 LABORATORY - SEIKO RT-3000 ROBOT
- •10.7 TUTORIAL - SEIKO RT-3000 ROBOT
- •10.8 LABORATORY - ASEA IRB-1000 ROBOT
- •10.9 TUTORIAL - ASEA IRB-1000 ROBOT
- •11. ROBOT APPLICATIONS
- •11.0.1 Overview
- •11.0.2 Spray Painting and Finishing
- •11.0.3 Welding
- •11.0.4 Assembly
- •11.0.5 Belt Based Material Transfer
- •11.1 END OF ARM TOOLING (EOAT)
- •11.1.1 EOAT Design
- •11.1.2 Gripper Mechanisms
- •11.1.2.1 - Vacuum grippers
- •11.1.3 Magnetic Grippers
- •11.1.3.1 - Adhesive Grippers
- •11.1.4 Expanding Grippers
- •11.1.5 Other Types Of Grippers
- •11.2 ADVANCED TOPICS
- •11.2.1 Simulation/Off-line Programming
- •11.3 INTERFACING
- •11.4 PRACTICE PROBLEMS
- •11.5 LABORATORY - ROBOT INTERFACING
- •11.6 LABORATORY - ROBOT WORKCELL INTEGRATION
- •12. SPATIAL KINEMATICS
- •12.1 BASICS
- •12.1.1 Degrees of Freedom
- •12.2 HOMOGENEOUS MATRICES
- •12.2.1 Denavit-Hartenberg Transformation (D-H)
- •12.2.2 Orientation
- •12.2.3 Inverse Kinematics
- •12.2.4 The Jacobian
- •12.3 SPATIAL DYNAMICS
- •12.3.1 Moments of Inertia About Arbitrary Axes
- •12.3.2 Euler’s Equations of Motion
- •12.3.3 Impulses and Momentum
- •12.3.3.1 - Linear Momentum
- •12.3.3.2 - Angular Momentum
- •12.4 DYNAMICS FOR KINEMATICS CHAINS
- •12.4.1 Euler-Lagrange
- •12.4.2 Newton-Euler
- •12.5 REFERENCES
- •12.6 PRACTICE PROBLEMS
- •13. MOTION CONTROL
- •13.1 KINEMATICS
- •13.1.1 Basic Terms
- •13.1.2 Kinematics
- •13.1.2.1 - Geometry Methods for Forward Kinematics
- •13.1.2.2 - Geometry Methods for Inverse Kinematics
- •13.1.3 Modeling the Robot
- •13.2 PATH PLANNING
- •13.2.1 Slew Motion
- •13.2.1.1 - Joint Interpolated Motion
- •13.2.1.2 - Straight-line motion
- •13.2.2 Computer Control of Robot Paths (Incremental Interpolation)
- •13.3 PRACTICE PROBLEMS
- •13.4 LABORATORY - AXIS AND MOTION CONTROL
- •14. CNC MACHINES
- •14.1 MACHINE AXES
- •14.2 NUMERICAL CONTROL (NC)
- •14.2.1 NC Tapes
- •14.2.2 Computer Numerical Control (CNC)
- •14.2.3 Direct/Distributed Numerical Control (DNC)
- •14.3 EXAMPLES OF EQUIPMENT
- •14.3.1 EMCO PC Turn 50
- •14.3.2 Light Machines Corp. proLIGHT Mill
- •14.4 PRACTICE PROBLEMS
- •14.5 TUTORIAL - EMCO MAIER PCTURN 50 LATHE (OLD)
- •14.6.1 LABORATORY - CNC MACHINING
- •15. CNC PROGRAMMING
- •15.1 G-CODES
- •15.3 PROPRIETARY NC CODES
- •15.4 GRAPHICAL PART PROGRAMMING
- •15.5 NC CUTTER PATHS
- •15.6 NC CONTROLLERS
- •15.7 PRACTICE PROBLEMS
- •15.8 LABORATORY - CNC INTEGRATION
- •16. DATA AQUISITION
- •16.1 INTRODUCTION
- •16.2 ANALOG INPUTS
- •16.3 ANALOG OUTPUTS
- •16.4 REAL-TIME PROCESSING
- •16.5 DISCRETE IO
- •16.6 COUNTERS AND TIMERS
- •16.7 ACCESSING DAQ CARDS FROM LINUX
- •16.8 SUMMARY
- •16.9 PRACTICE PROBLEMS
- •16.10 LABORATORY - INTERFACING TO A DAQ CARD
- •17. VISIONS SYSTEMS
- •17.1 OVERVIEW
- •17.2 APPLICATIONS
- •17.3 LIGHTING AND SCENE
- •17.4 CAMERAS
- •17.5 FRAME GRABBER
- •17.6 IMAGE PREPROCESSING
- •17.7 FILTERING
- •17.7.1 Thresholding
- •17.8 EDGE DETECTION
- •17.9 SEGMENTATION
- •17.9.1 Segment Mass Properties
- •17.10 RECOGNITION
- •17.10.1 Form Fitting
- •17.10.2 Decision Trees
- •17.11 PRACTICE PROBLEMS
- •17.12 TUTORIAL - LABVIEW BASED IMAQ VISION
- •17.13 LABORATORY - VISION SYSTEMS FOR INSPECTION
- •18. INTEGRATION ISSUES
- •18.1 CORPORATE STRUCTURES
- •18.2 CORPORATE COMMUNICATIONS
- •18.3 COMPUTER CONTROLLED BATCH PROCESSES
- •18.4 PRACTICE PROBLEMS
- •18.5 LABORATORY - WORKCELL INTEGRATION
- •19. MATERIAL HANDLING
- •19.1 INTRODUCTION
- •19.2 VIBRATORY FEEDERS
- •19.3 PRACTICE QUESTIONS
- •19.4 LABORATORY - MATERIAL HANDLING SYSTEM
- •19.4.1 System Assembly and Simple Controls
- •19.5 AN EXAMPLE OF AN FMS CELL
- •19.5.1 Overview
- •19.5.2 Workcell Specifications
- •19.5.3 Operation of The Cell
- •19.6 THE NEED FOR CONCURRENT PROCESSING
- •19.7 PRACTICE PROBLEMS
- •20. PETRI NETS
- •20.1 INTRODUCTION
- •20.2 A BRIEF OUTLINE OF PETRI NET THEORY
- •20.3 MORE REVIEW
- •20.4 USING THE SUBROUTINES
- •20.4.1 Basic Petri Net Simulation
- •20.4.2 Transitions With Inhibiting Inputs
- •20.4.3 An Exclusive OR Transition:
- •20.4.4 Colored Tokens
- •20.4.5 RELATIONAL NETS
- •20.5 C++ SOFTWARE
- •20.6 IMPLEMENTATION FOR A PLC
- •20.7 PRACTICE PROBLEMS
- •20.8 REFERENCES
- •21. PRODUCTION PLANNING AND CONTROL
- •21.1 OVERVIEW
- •21.2 SCHEDULING
- •21.2.1 Material Requirements Planning (MRP)
- •21.2.2 Capacity Planning
- •21.3 SHOP FLOOR CONTROL
- •21.3.1 Shop Floor Scheduling - Priority Scheduling
- •21.3.2 Shop Floor Monitoring
- •22. SIMULATION
- •22.1 MODEL BUILDING
- •22.2 ANALYSIS
- •22.3 DESIGN OF EXPERIMENTS
- •22.4 RUNNING THE SIMULATION
- •22.5 DECISION MAKING STRATEGY
- •23. PLANNING AND ANALYSIS
- •23.1 FACTORS TO CONSIDER
- •23.2 PROJECT COST ACCOUNTING
- •24. REFERENCES
- •25. APPENDIX A - PROJECTS
- •25.1 TOPIC SELECTION
- •25.1.1 Previous Project Topics
- •25.2 CURRENT PROJECT DESCRIPTIONS
- •26. APPENDIX B - COMMON REFERENCES
- •26.1 JIC ELECTRICAL SYMBOLS
- •26.2 NEMA ENCLOSURES
page 89
4.Call the Information technology people on campus, and request an IP address. Also ask for the gateway number, netmask, and nameserver numbers. They will add your machine to the campus DNS so that others may find it by name (the number will always work if chosen properly).
5.Connect the computer to the network, then turn it on.
6.Install Windows NT, and when asked provide the network information. Indicate that web serving will be permitted.
7.Modify web pages as required.
4.4.5 Java
•This is a programming language that is supported on most Internet based computers.
•These programs will run on any computer - there is no need for a Mac, PC and Unix version.
•Most users don’t need to program in Java, but the results can be used in your web pages
4.4.6 Javascript
• Simple programs can be written as part of an html file that will add abilities to the HTML page.
4.4.7 CGI
•CGI (Common Gateway Interface) is a very popular technique to allow the html page on the client to run programs on the server.
•Typical examples of these include,
-counters
-feedback forms
-information requests
4.5 NETWORKING IN LINUX
page 90
Configuration files are under /etc
Recompile kernel in some cases, such as a firewall. or new hardware
Loadable modules
DHCP versus static IP
Most modern versions of Linux simplify hardware detection and setup. The steps below can help perform the basic operations, or find problems.
A.Installing a normal ethernet network connection:
1.During the installation process you will be asked for network parameters.
2.Enter a unique name for the machine and the network name.
3.(for DHCP) All that should be required is a setting for DHCP.
3.(for a static IP) You will need to enter the static IP number for the machine, as well as a netmask and gateway. If you are connecting to another network you can get these from a network administrator. If you are connecting your own network (not on the Internet) you can simply pick values like those below. Note that you need some sort of network router with an IP address of 192.168.1.254 for this to work.
IP address: 192.168.1.20 netmask: 255.255.255.0 Gateway: 192.168.1.254 nameserver: none
B.Troubleshooting an ethernet connection to the Internet,
1.Check to see if the network card is recognized with ’more /proc/modules’ The card should be in the list. If not the kernel module must be installed.
2.Check to see if the network is setup with ifconfig. You should see ’eth0’ or something similar. If it is not setup, the network parameters must be checked.
3.Check to see if the network is connected properly with ping to the local gateway, or another local machine - use the IP number, not the name. For example, ’ping 148.61.104.254’. If this fails the gateway or broadcast addresses are probably incorrect.
4.Check the connection to the outside with a ping such as ’ping 148.61.1.10’. If this is not allowed there is probably a problem with the outside connection
5.Verify that the nameserver is working alright with a ping to a named machine such as, ’ping www.linux.org’.
6.If all of these things work the network connection should be alright.
C.Installing a dialup connection
1.During the installation make sure that the location of your modem is correctly identified. Note: Winmodems are very popular because of their low cost, but there are very few Linux drivers. But... you are advised to spend the money for a non-Win- modem anyway, they are more reliable and they don’t use your computers
page 91
resources.
2.
D.Troubleshooting a dialup connection
1.Use a terminal program to dial the Internet service provider’s number manually. If you don’t get a response there is a problem with the modem installation.
2.After connected try providing your login ID and password and see if you get in. Expect to see garbage after this. If login is refused you need to check the user ID and password again.
3.Check ...
E.Setting up a firewall (this requires some work)
1.To set up a firewall the kernel must be recompiled to include network options such as multicasting, and firewall services.
[KERNEL OPTIONS]
2.Shut down the computer and add a second network card in the machine and reboot.
3.Check to see if the card is recognized with ’more /proc/modules’. Both ethernet cards should be listed. If not you will need to edit the network startup files. These are normally in ’/etc/...’ or for slackware ’/etc/rc.d’. An example file follows. Reboot and check for both network cards again.
[NETWORK CONFIG FILES]
4.Use ’ipchains’ to add services to pass, and modify the ’hosts.allow’ and ’hosts.deny’ files to control access.
[ipchains file declarations] [hosts.allow file] [hosts.deny file]
4.5.1 Network Programming in Linux
The following listings show network usage in Linux. The general method of network connection is different for servers and clients.
For servers.....
For clients....
Listing X.1 - network_io.cpp
page 92
#include "network_io.h"
#include <sys/poll.h> #include <sys/ioctl.h> #include <linux/tcp.h>
#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h>
network_io::network_io(){ type = _READ; level = 0;
}
network_io::~network_io(){
if(type == _READ){
if(level > 1){
if(level > 2){
end_read_connection();
}
deinit_read();
}
} else if (type == _WRITE){
}
}
int network_io::set_remote_host(char *_host_name, int host_socket){
static |
int |
error; |
static |
int |
nm_a, |
nm_b, nm_c, nm_d;
struct hostent*hp; unsigned charaddress[4];
error = NO_ERROR; strcpy(host_name, _host_name); host_socket_number = host_socket;
// Set up server descriptor, get host reference and error trap write_connection.sin_family = AF_INET;
if((host_name[0] > ’9’) ||(host_name[0]<’0’)){ hp = gethostbyname(host_name);
} else {
sscanf(host_name, "%d.%d.%d.%d", &nm_a, &nm_b, &nm_c, &nm_d);
address[0] = (unsigned char)(nm_a); address[1] = (unsigned char)(nm_b); address[2] = (unsigned char)(nm_c); address[3] = (unsigned char)(nm_d);
hp = gethostbyaddr((char *)address, 4, AF_INET);
}
if(hp != 0){
/* complete descriptor set up. */ bcopy((char *)hp->h_addr,
page 93
(char *)&(write_connection.sin_addr), hp->h_length);
} else {
error_log(MINOR, "ERROR: unknown network host"); error = ERROR;
}
return error;
}
int network_io::set_local_host(int socket_num){ static int error;
error = NO_ERROR; socket_number = socket_num;
return error;
}
int network_io::writer(char *string){
static int |
error; |
error = NO_ERROR; |
|
// Open a new socket for the write, and check for errors.
error = init_write(); |
|
if(error == NO_ERROR) error |
= open_write_connection(); |
if(error == NO_ERROR) error |
= write_to_connection(string); |
if(error == NO_ERROR) error |
= end_write_connection(); |
if(deinit_write() == ERROR) |
error = ERROR; |
return(error); |
|
} |
|
int network_io::reader(char *buf, int length){ |
|
static interror; |
// Error return variable |
error = NO_ERROR;
// Wait for a socket connection request, then get its reference. buf[0] = 0;
if(wait_read_connection() == NO_ERROR){
if(read_from_connection(buf, length) == ERROR){
}
// Close socket connection to remote write client. end_read_connection();
}
return(error);
}
int network_io::init_write(){
static int |
error; |
|
struct hostent |
*gethostbyname(); |
|
error = |
NO_ERROR; |
|
/* Open |
a new |
socket for the write, and check for errors. */ |
if((rw_socket |
= socket(AF_INET, SOCK_STREAM, 0)) >= 0){ |
page 94
write_connection.sin_port = htons(host_socket_number);
} else {
error_log(MINOR, "ERROR: opening stream socket"); error = ERROR;
}
return error;
}
int network_io::open_write_connection(){
static int error;
error = NO_ERROR;
if(connect(rw_socket, (struct sockaddr *) &(write_connection), sizeof(write_connection))
< 0){
error = ERROR;
error_log(MINOR, "ERROR: Connecting stream Socket");
}
return error;
}
int network_io::write_to_connection(char *text){
static int error;
error = NO_ERROR;
if(write(rw_socket, text, strlen(text) /* +1 */) < 0){
error_log(MINOR, "ERROR: writing on stream socket"); error = ERROR;
}
return error;
}
int network_io::write_stuff_done(){ int error;
error = NO_ERROR; return error;
}
int network_io::check_connection(){
int |
error; |
int |
count; |
struct pollfd ufds;
error = NO_ERROR; ufds.fd = rw_socket;
ufds.events = POLLOUT | POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; count = poll(&ufds, 1, 0);
if((ufds.revents & 16) != 0) error = ERROR;
return error;
}
int network_io::end_write_connection(){ static int error;
error = NO_ERROR;
page 95
return error;
} |
|
|
int network_io::deinit_write(){ |
|
|
static int error; |
|
|
error = NO_ERROR; |
|
|
close(rw_socket); |
|
|
rw_socket = ANY; |
|
|
return error; |
|
|
} |
|
|
int network_io::init_read(){ |
|
|
static int |
error; |
// low level socket number |
unsigned |
length; |
// temporary work variable |
static struct sockaddr_inserver; // read socket descriptor |
||
static struct hostent*hp; |
|
|
char |
text[100]; |
|
// Open internet socket, and check for error. |
||
error = ERROR; |
|
|
gethostname(text, 100); |
/* who are we? */ |
hp = gethostbyname(text);
if((hp != NULL) && (read_socket = socket(AF_INET, SOCK_STREAM, 0)) >= 0){
//Set up server descriptor for binding name. memset(&server, 0, sizeof(struct sockaddr_in)); server.sin_family = hp->h_addrtype; server.sin_port = htons(socket_number);
//Bind the socket, and check for error.
level = 1; int flag = 1;
setsockopt(read_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(int)); if(bind(read_socket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) >=
0){
// Check for valid socket binding length = sizeof(server);
if(getsockname(read_socket, (struct sockaddr *)&server, &length) >=
0){
error = NO_ERROR;
//Set up variables for success
//Zero because anything higher would allow
//messages to arrive out of sequence. listen(read_socket, 0);
} else {
error_log(MINOR, "ERROR: getting socket name");
}
} else {
error_log(MINOR, "ERROR: binding stream socket");
}
} else {
error_log(MINOR, "ERROR: opening stream socket");
}
return(error);
}
int network_io::read_stuff_waiting(){ int error,
count; struct pollfd ufds;
page 96
error = ERROR; ufds.fd = read_socket;
ufds.events = POLLIN | POLLPRI | POLLOUT; count = poll(&ufds, 1, 0); if((ufds.revents & 1) > 0){
error = NO_ERROR;
}
return error;
}
int network_io::wait_read_connection(){
static int error;
unsigned size;
static struct sockaddr addr;
error = NO_ERROR;
size = sizeof(struct sockaddr); fcntl(read_socket, F_SETFL, O_NONBLOCK); rw_socket = accept(read_socket, &addr, &size);
level = 2; if(rw_socket < 0){
error = ERROR;
// error_log("ERROR: warning:accept");
}
return error;
}
int network_io::read_from_connection(char *buf, int length){
int |
error; |
int |
len; |
error = NO_ERROR;
//Empty input buffer buf[0] = 0;
//Read string into buffer from socket fcntl(rw_socket, F_SETFL, O_NONBLOCK); len = read(rw_socket, buf, length); if(len < 0){
//error_log("ERROR: reading stream message");
//error = ERROR;
if(errno != 11){
printf("errno=%d ", errno);
}
} else {
buf[len] = 0;
}
return error;
}
int network_io::end_read_connection(){
int |
error; |
int |
a; |
error = NO_ERROR;
a = close(rw_socket); level = 1;
page 97
return error;
}
int network_io::deinit_read(){
int |
error; |
int |
a; |
error = NO_ERROR;
a = close(read_socket); level = 0;
return error;
}
char *network_io::get_address(){
static char |
work[MAXIMUM_HOST_NAME_LENGTH]; |
struct sockaddr_inaddress; |
|
int |
i, |
|
addr[4]; |
long |
int_address; |
#ifndef SGI
// Sun Version get_myaddress(&address);
int_address = address.sin_addr.s_addr;
#else
// SGI Version int_address = gethostid();
#endif
// SUN & SGI version for(i = 0; i < 4; i++){
addr[i]=int_address & 0xFF; int_address >>= 8;
}
#ifdef OTHER_UNIX
sprintf(work, "%d.%d.%d.%d",
(int)addr[3], (int)addr[2], (int)addr[1], (int)addr[0]);
#else
// This is for linux sprintf(work, "%d.%d.%d.%d",
(int)addr[0], (int)addr[1], (int)addr[2], (int)addr[3]);
#endif
return work;
}
char *network_io::get_remote_client(){
staticchar |
work[100]; |
struct sockaddr |
address; |
socklen_t |
len; |
len = sizeof(address);
if(getpeername(rw_socket, &address, &len) == 0){
sprintf(work, "%u.%u.%u.%u", address.sa_data[2], address.sa_data[3], address.sa_data[4], address.sa_data[5]);
// printf("Got address [%s]\n", work); //strcpy(work, address);
} else {
strcpy(work, "unknown network address");
}
return work;
}
page 98
Listing X.2 - network_io.h
#ifndef _NETWORK_IO #define _NETWORK_IO
#include <errno.h> #include <linux/socket.h> #include <sys/types.h> #include <netdb.h> #include <rpc/rpc.h> #include <unistd.h>
#define ANY |
0 |
|
// Indicates no socket number prechosen |
#define |
MAXIMUM_HOST_NAME_LENGTH100 |
||
class network_io{ |
|
|
|
public: |
|
|
|
|
int |
|
socket_number; |
|
int |
|
rw_socket; |
|
// int |
|
read_connection; |
|
char |
host_name[MAXIMUM_HOST_NAME_LENGTH]; |
|
|
int |
|
host_socket_number; |
|
int |
|
read_socket; |
|
struct sockaddr_inwrite_connection; |
||
|
// char |
incoming_string[MAXIMUM_STRING_SIZE]; |
|
|
int |
|
type; |
|
int |
|
level; |
|
#define |
_READ |
200 |
|
#define |
_WRITE |
201 |
|
|
|
network_io(); |
|
|
|
~network_io(); |
|
int |
|
set_remote_host(char*, int); |
|
int |
|
set_local_host(int); |
|
int |
|
reader(char*, int); |
|
int |
|
writer(char*); |
|
int |
|
init_write(); |
|
int |
|
open_write_connection(); |
|
int |
|
write_to_connection(char*); |
|
// int |
|
write_to_read_connection(char*); |
|
int |
|
end_write_connection(); |
|
int |
|
deinit_write(); |
|
int |
|
init_read(); |
|
int |
|
wait_read_connection(); |
|
int |
|
read_from_connection(char*, int); |
|
// int |
|
read_from_write_connection(char*, int); |
|
int |
|
end_read_connection(); |
|
int |
|
deinit_read(); |
|
int |
|
read_stuff_waiting(); |
|
int |
|
write_stuff_done(); |
|
int |
|
check_connection(); |
|
char* |
get_remote_client(); |
|
|
char |
*get_address(); |
|
}; |
|
|
|
page 99
#endif
Listing X.3 - network.cpp
#include "../network_io/network_io.h" #include <time.h>
network_io *network; |
|
|
int |
mode; |
|
char |
*params; |
|
char |
received_temp[200]; |
|
int |
connect_flag; |
|
time_t |
now_time; |
|
time_t |
last_time; |
|
int |
timeout; |
|
int main(){ |
|
|
timeout = 5; |
// the default timeout |
|
return 1; |
|
|
} |
|
|
int deinit(){ |
|
|
int |
error; |
|
error = NO_ERROR;
if(network != NULL) delete network;
return error;
}
int process_command(); int check_network();
int step(){
int error;
error = NO_ERROR;
error = check_network();
if(error == NO_ERROR) error = process_command();
return error;
}
int check_network(){
int |
error; |
error = NO_ERROR; |
if(*state == WAITINGFORCONNECTION){ if(connect_flag == TRUE){
page 100
if(mode == LISTENER){
if(network->wait_read_connection() == NO_ERROR){ char text[200];
*state = CONNECTIONESTABLISHED; *received_flag = FALSE; *send_flag = FALSE;
sprintf(text, "Got a connection from %s", network-
>get_remote_client());
error_log(WARNING, text); time(&last_time);
}
} else if(mode == TALKER){ if(network->open_write_connection() == NO_ERROR){
*state = CONNECTIONESTABLISHED; *received_flag = FALSE; *send_flag = FALSE; time(&last_time);
}
}
}
} else if(*state == CONNECTIONESTABLISHED){ if(*send_flag == TRUE){
network->write_to_connection(send_buf);
//printf("Sending String [%s]\n", send_buf); send_buf[0] = 0;
*send_flag = FALSE;
//time(&last_time); // You can keep the connection alive by writing
//but this doesn’t guarantee that the remote client is still there
}
if(*received_flag == FALSE){ if(network->read_from_connection(received_temp, 199) != ERROR){
if(strlen(received_temp) > 0){ strcpy(received, received_temp); *received_flag = TRUE; time(&last_time);
// printf("Got String [%s]\n", received);
}
}
}
time(&now_time);
if((network->check_connection() == ERROR) || ((mode == LISTENER) && (difftime(now_time, last_time) > timeout))){
if(mode == LISTENER){ network->end_read_connection();
} else if(mode == TALKER){ network->end_write_connection();
}
*state = WAITINGFORCONNECTION; connect_flag = FALSE;
}
}
return error;
}
int process_command(){
int |
error; |
int |
i, len; |
int |
port; |
error = NO_ERROR; if(*change_lock == TRUE){
if(*command == INITIALIZE){
page 101
if(*state == NOTINITIALIZED){ if(mode == LISTENER){
port = atoi(params); if(port > 0){
network = new network_io(); network->set_local_host(port); network->init_read();
//now ready to listen
*state = WAITINGFORCONNECTION; connect_flag = FALSE;
} else {
error_log(MINOR, "Parameter did not hold
a valid port");
*error_flag = ERROR;
}
} else if(mode == TALKER){
len = strlen(params); for(i = 0; i < len; i++){
if(params[i] == ’:’){ params[i] = 0;
port = atoi(&(params[i+1])); break;
}
}
if((i < len) && (port > 0)){
network = new network_io(); network->set_remote_host(params, port); network->init_write();
*state = WAITINGFORCONNECTION; connect_flag = FALSE;
} else {
error_log(MINOR, "Address string was not
properly formed");
*error_flag = ERROR;
}
} else {
error_log(MINOR, "ERROR: Mode not defined yet"); *error_flag = ERROR;
}
} else {
error_log(MINOR, "Network talker initialize command in wrong
state");
*error_flag = ERROR;
}
} else if(*command == CONNECT){
if(*state == WAITINGFORCONNECTION){ connect_flag = TRUE;
}
} else if(*command == DISCONNECT){
if(*state == CONNECTIONESTABLISHED){ if(mode == TALKER){
network->end_write_connection(); } else if (mode == LISTENER){
network->end_read_connection();
}
*state = WAITINGFORCONNECTION; connect_flag = FALSE;
} else {
error_log(MINOR, "Cannot disconnect network unless
connected");
*error_flag = ERROR;
}
} else if(*command == UNINITIALIZE){ if(*state == WAITINGFORCONNECTION){
if(mode == TALKER){