📄 net_udp.cpp
字号:
// TCP/IP network functions for use with mechatronics control programs
// Created 12/30/96, DM Auslander
// These functions are based on User Datagram Protocol (UDP)
#include <winsock.h> // Winsock header file
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include <sys\timeb.h> // for ftime()
#include "net_udp.hpp"
#define WINSOCK_VERSION 0x0101 // Program requires Winsock version 1.1
#define SEND_FLAGS 0 // No send() flags specified
#define RECV_FLAGS 0 // No recv() flags specified
#define BASE_PORT 1234 // Base address for ports
#define INTELx86 0 // Data format code
static SOCKET nSocket; // Socket handle used by this program
// Packet information
#define MAX_PROC 50
#define PACKET_BUFFER_SIZE 5000
#define ADDRESS_SIZE 20
static unsigned char *pPacketBuffer[MAX_PROC]; // Pointers to buffers
// for outgoing packets
static int PacketNext[MAX_PROC]; // Indexes into packet buffers
static int ThisProcess,NumProc;
static unsigned long ProcessAddress[MAX_PROC]; // Internet addresses
static int ProcessConnected[MAX_PROC]; // Indicates when process is
// connected to net
static int NetConnected;
// Unions used for coding/decoding packets
union pack_short
{
short s;
unsigned char c[2];
};
union pack_double
{
double d;
unsigned char c[8];
};
// Data block codes. Only two types of blocks are recognized
// for control programs: messages and shared data. Any number
// of these can be mixed in a single packet.
// Block codes:
// Structures
// 1 standard message
// 2 shared data array
// Functions to extract information from a packet
int ExtractShortValue(unsigned char *packet_array,int next,int *pvalue)
{
union pack_short pp;
int i = next;
pp.c[0] = packet_array[i++];
pp.c[1] = packet_array[i++];
*pvalue = (int)pp.s;
return(i);
}
int ExtractDoubleValue(unsigned char *packet_array,int next,double *pvalue)
{
union pack_double pp;
int i = next;
for(int j = 0;j < 8; j++)pp.c[j] = packet_array[i++];
*pvalue = pp.d;
return(i);
}
int ExtractDoubleArray(unsigned char *packet_array,int next,
double **pvalue,int *pnval,int *size)
{
int i = next;
int nval,j;
double v,*pv;
i = ExtractShortValue(packet_array,i,&nval); // Get number of values
*pnval = nval;
if(nval > *size)
{
if(*size > 0)delete [] pvalue; // Delete old array
*pvalue = new double [nval + 20]; // Create larger array
*size = nval + 20; // Return new size value
}
pv = *pvalue;
for(j = 0; j < nval; j++)
{
i = ExtractDoubleValue(packet_array,i,&v);
pv[j] = v; // store array value
}
return(i);
}
// Storage for double array
static int vSize = 0; // Initial size of array
static double *v;
int ParseMessage(unsigned char *Buf,int nCharRecv)
{
// Break out component parts of the message and print results
// Return 0 for OK, -1 for error
int nused = 0; // Number of characters used in decoding buffer
if(Buf[nused++] != INTELx86)
{
// Incorrect data format (Only Intelx86 recognized here)
cout << "<ParseMessage> Incorrect data format, 1st char = "
<< (int)Buf[0] << "\n";
return(-1);
}
while(nused < nCharRecv)
{
// Continue this loop until the message is entirely consumed
int BlockType = Buf[nused++];
switch(BlockType)
{
case 1: // Message block
{
int ToProc,ToTask,BoxNo,FromProc,FromTask;
int MsgFlag,RetRecpt,DelMode;
double MsgValue;
nused = ExtractShortValue(Buf,nused,&ToProc);
nused = ExtractShortValue(Buf,nused,&ToTask);
nused = ExtractShortValue(Buf,nused,&BoxNo);
nused = ExtractShortValue(Buf,nused,&FromProc);
nused = ExtractShortValue(Buf,nused,&FromTask);
nused = ExtractShortValue(Buf,nused,&MsgFlag);
nused = ExtractDoubleValue(Buf,nused,&MsgValue);
nused = ExtractShortValue(Buf,nused,&RetRecpt);
nused = ExtractShortValue(Buf,nused,&DelMode);
StoreMessage(ToProc,ToTask,BoxNo,FromProc,
FromTask,MsgFlag,MsgValue,RetRecpt,DelMode);
break;
}
case 2: // Shared value array
{
int n,ToProc,ToTask;
nused = ExtractShortValue(Buf,nused,&ToProc);
nused = ExtractShortValue(Buf,nused,&ToTask);
nused = ExtractDoubleArray(Buf,nused,&v,&n,&vSize);
StoreSharedData(ToProc,ToTask,n,v);
break;
}
case 100: // Are-you-there packet
{
unsigned char *pbuf;
int iNext;
if(Buf[nused++] != ThisProcess)
{
cout << "<Parse> Incorrect proc # in ARE-YOU-THERE\n";
return(-1);
}
// Respond to Process 0 with I-AM-HERE
pbuf = pPacketBuffer[0]; // Pointer to buffer
iNext = PacketNext[0]; // Next free slot
// 1st byte for Intel data format (already there)
pbuf[iNext++] = 101; // 2nd byte indicates I-AM-HERE
pbuf[iNext++] = (unsigned char)ThisProcess;
// 3rd byte has number of this process
PacketNext[0] = iNext;
if(SendData() != 0) // Send out Packets
{
cout << "<ContactProcesses> Error sending I-AM-HERE data\n";
return(1);
}
break;
}
case 101: // I-AM-HERE packet
{
int FromProc;
FromProc = Buf[nused++];
if((FromProc < 0) || (FromProc >= NumProc))
{
cout << "<Parse> Invalid ProcNo in I-AM-HERE "
<< FromProc << "\n";
return(1);
}
ProcessConnected[FromProc] = 1;
break;
}
case 102: // START packet
{
if(Buf[nused++] != ThisProcess)
{
cout << "<Parse> Incorrect proc # in ARE-YOU-THERE\n";
return(-1);
}
NetConnected = 1;
break;
}
default:
// No other type implemented
cout << "\nUnknown Block Type\n";
return(-1);
}
}
//cout << "\nEnd of Packet\n";
return(0);
}
// Functions for assembling a packet
int InsertShortValue(unsigned char *packet_array,int npack,int value)
{
union pack_short ps;
int i = npack;
if((int)((short)value) != value)
{
cout << "<InsertShortValue> Truncation error\n";
exit(6);
}
ps.s = (short)value;
packet_array[i++] = ps.c[0];
packet_array[i++] = ps.c[1];
return(i);
}
int InsertDoubleValue(unsigned char *packet_array,int npack,double value)
{
union pack_double pd;
int i = npack;
pd.d = value;
for(int j = 0; j < 8; j++)packet_array[i++] = pd.c[j];
return(i);
}
int InsertDoubleArray(unsigned char *packet_array,int npack,
double *array,int nval)
{
union pack_double pd;
union pack_short ps;
int i = npack;
ps.s = (short)nval; // Enter number of values in array
packet_array[i++] = ps.c[0];
packet_array[i++] = ps.c[1];
for(int k = 0; k < nval; k++) // Enter the array values
{
pd.d = array[k];
for(int j = 0; j < 8; j++)packet_array[i++] = pd.c[j];
}
return(i);
}
union AddressConvert // To get dotted-decimal addresses
// from 32-bit addresses, or vice-versa
{
u_long IPAddr;
struct
{
u_char b1,b2,b3,b4;
}bbb;
};
int ResetPacket(int iProc)
{
unsigned char *pc;
// Returns error: 1 for error, 0 for OK
if(iProc == ThisProcess)
{
// No packet buffer needed for this process
pPacketBuffer[iProc] = NULL;
return(0);
}
if(pPacketBuffer[iProc] == NULL)
{
// Allocate new memory
pc = new unsigned char [PACKET_BUFFER_SIZE];
if(pc == NULL)
{
cout << "<ResetPacket> Can't allocate packet buffer\n";
return(1);
}
pPacketBuffer[iProc] = pc; // Pointer to space for packet assembly
}
pc = pPacketBuffer[iProc];
pc[0] = INTELx86; // Data format code
PacketNext[iProc] = 1; // First character is always the data format
return(0);
}
void NetCleanUp(void)
{
if(vSize > 0)delete [] v; // Free memory used for buffer
WSACleanup(); // Free all allocated program resources
// Free memory used for packet buffers
for(int i = 0; i < NumProc; i++)
{
if(pPacketBuffer[i] != NULL)
delete [] pPacketBuffer[i];
}
}
int ContactProcesses(void)
{
// Make sure all processes are on line before proceeding
// Process #0 is the master for this procedure
// It sends out probe packets to the other processes.
// When all processes have responded it sends out a
// START signal to all other processes
// Returns error: 1 for error, 0 for OK
// Probe packets are sent out at timed intervals to avoid
// network overload. The generic ftime() is used for timing
// so these functions can be tested independently of other
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -