This is TCPLib.m in view mode; [Download] [Up]
/* TCP Network Libary -- Implementation of Libary
BY: Kevin A. Hoogheem
Saint Mary's University of Minnesota
*/
#define TCPLIB_M
#ifndef TCPLIB_H
#import "TCPLib.h"
#endif
@implementation TCPNetwork
+ new
{
/*
* Purpose: To create a new Network object.
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
id newInstance = [super new];
[newInstance initialize];
return newInstance;
}
+ new: (int)sock_value
{
/*
* Purpose: To create a new Network object.
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
id newInstance = [super new];
[newInstance initialize:sock_value];
return newInstance;
}
- initialize
{
/*
* Purpose: Set the Sock to a initial value
*
* Input: Nothing
*
* Output:
*
* Return: True if all works - should always work
*
* Side Effects: Sock set to Initvalue
*/
sock = INITVAL;
return(self);
}
- initialize: (int)sock_val
{
/*
* Purpose: Set the sock to the sock_val
*
* Input: Nothing
*
* Output:
*
* Return: True if all works - should always work
*
* Side Effects: sock set to the sock_val
*/
sock = sock_val;
return(self);
}
- (int)open_port: (int)port
{
/*
* Purpose: Open a new network port, to be able to send traffic on it.
* User only chooses the port to open we will default to INET.
*
* Input: An integer for what port you want open.
*
* Output: NONE, unless errors in creating the socket and bind the
* sockets occur.
*
* Return: TRUE if all goes well :)-
*
* Side Effects: A new port on the network is opened up for communications.
*/
struct sockaddr_in sa;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0){
perror("Socket Creation Error");
return(FALSE);
}
bzero( (char *) &sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(port);
if (bind(sock,(struct sockaddr *) &sa, sizeof(sa)) < 0){
perror("Bind Error");
return(FALSE);
}
listen(sock, MAXLISTENS);
return(TRUE);
}
- (int)close_network
{
/*
* Purpose: To close the network so no traffic can be allow on it.
*
* Input:
*
* Output: NONE
*
* Return: TRUE if all goes well.
*
* Side Effects: The network is closed.
*/
close(sock);
return(TRUE);
}
- (int)call: (char *)machine_name on_port: (int)port
{
/*
* Purpose: To call a networked machine on a specified port.
* Allows you to use anything for the other machines name
* ie.. either his actual name or his ip address.
*
* Input: A remote machine name and its port you want to contact.
*
* Output:
*
* Return: TRUE if all goes well ;)-
*
* Side Effects: Opens a channel of communication to a remote machine.
*/
struct sockaddr_in sa;
struct hostent *hp;
struct in_addr *addr_ptr;
char *temp_ip = '\0';
strcpy(temp_ip, machine_name);
if (isdigit( *(temp_ip + 1)) ){
bzero((char *) &sa, sizeof(sa));
sa.sin_family =AF_INET;
sa.sin_addr.s_addr =inet_addr(machine_name);
sa.sin_port =htons(port);
if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("Socket Creation Error");
return(FALSE);
}
}else{
if ( (hp = gethostbyname(machine_name) ) == NULL){
perror("Get host name error");
return(FALSE);
}else{
addr_ptr = (struct in_addr*) *(hp->h_addr_list);
machine_name = inet_ntoa(*addr_ptr);
}
bzero((char *) &sa, sizeof(sa));
bcopy(hp->h_addr,(char *)&sa.sin_addr,hp->h_length);
sa.sin_family =hp->h_addrtype;
sa.sin_port =htons(port);
if ( (sock = socket(sa.sin_family, SOCK_STREAM, 0)) < 0){
perror("Socket Creation Error");
return(FALSE);
}
}
if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0){
perror("Connection Error");
return(FALSE);
}
return(TRUE);
}
- (int)call: (char *)machine using: (char *)protocol
{
/*
* Purpose: To call a networked machine using a well known protocol.
*
* Input: A remote machine name and the protcol you wish to use in
* contacting it. From /etc/services
*
* Output:
*
* Return:
*
* Side Effects:
*/
// not needed at this time.
return self;
}
- (int)send_text: (char *)message
{
/*
* Purpose: To send desired text message. (must find its own length)
*
* Input: A character String message.
*
* Output:
*
* Return: Return How much was writen or True if all works well.
*
* Side Effects:
*/
int length, written;
length = strlen(message)+1;
written = write(sock, message ,length);
if (written != length){
perror("Send_Text Error");
return(written);
}
return(TRUE);
}
- (int)send_text: (char *)message of_length: (int)length
{
/*
* Purpose: Send a (length) fixed message.
*
* Input: A character string message and its length.
*
* Output:
*
* Return: On Error return how much was writen to the Socket. Or 0 if works.
*
* Side Effects:
*/
int nleft, nwritten;
nleft = length;
while ( nleft > 0 ){
nwritten = write(sock, message, nleft);
if( nwritten <= 0 )
return(nwritten);
nleft -= nwritten;
message += nwritten;
}
return (length - nleft);
}
- (int)send_file: (char *)file
{
/*
* Purpose: To send a file accrose the network.
*
* Input: The name of a file.
*
* Output:
*
* Return: An int representing an error while trying to access the file.
*
* Side Effects:
*/
return self;
}
- (int)readline: (char *)ptr of_length: (int)maxlen
{
/*
* Read a line from a descriptor. Read the line one byte at a time,
* looking for the newline. We store the newline in the buffer,
* then follow it with a null ( the same as fgets(3)).
* We return the number of characters up to, but not including,
* the null (the same as strlen(3)).
*/
int n, rc;
char c;
for (n=1; n < maxlen; n++){
if ( (rc = read(sock, &c, 1)) == 1){
*ptr++ = c;
if ( c == '\n')
break;
}else
if (rc == 0 ){
if (n == 1)
return(0); /* EOF, no data read */
else
break; /* EOF, some data was read */
}else
return(-1); /* ERROR */
}
*ptr = 0;
return (n);
}
- (int)receive
{
/*
* Purpose: Used to set up a client user allow
*
* Input:
*
* Output:
*
* Return: the new sock for the client to activate a new network obj.
*
* Side Effects: Accepts on a socket.
*/
struct sockaddr_in sa;
int length;
int t;
length = sizeof(sa);
if ((t = accept(sock,(struct sockaddr *)&sa, &length)) < 0) {
perror("tcp error accept");
return(FALSE);
}
if(DEBUG)
fprintf(stderr,"Connection from: %s\n",inet_ntoa(sa.sin_addr));
return(t);
}
- (int)recv_text: (char *)message
{
/*
* Purpose:
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
int length, nread;
length = strlen(message)+1;
nread = read(sock, message ,length);
if (nread != length){
perror("Recv_Text Error");
return(nread);
}
return(TRUE);
}
- (int)recv_text: (char *)message of_length: (int)length
{
/*
* Purpose:
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
int nleft, nread;
nleft = length;
while ( nleft > 0 ){
nread = read(sock, message, nleft);
if ( nread < 0 )
return(nread);
else
if ( nread == 0 )
break;
nleft -= nread;
message += nread;
}
return (length - nleft);
}
- recv_file: (char *)file
{
/*
* Purpose:
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
return(self);
}
- data_waiting
{
/*
* Purpose: Sit and wait for some data to arrive over the network.
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
return(self);
}
- call_waiting
{
/*
* Purpose: Sit and wait for a connection to occure.
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
return(self);
}
- get_remote_system_name;
{
/*
* Purpose:
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
return(self);
}
- get_remote_user_name;
{
/*
* Purpose:
*
* Input:
*
* Output:
*
* Return:
*
* Side Effects:
*/
return(TRUE);
}
- (int)get_service_port: (char *)service service_type: (int)type
{
/*
* Purpose: To get the port number of the service requested.
*
* Input: The service name and its type either DGRAM or STREAM
*
* Output:
*
* Return:
*
* Side Effects:
*/
// not needed at this time.
return(TRUE);
}
- print
{
/*
* Purpose: To debug the values of the object
*
* Input: NOTHING
*
* Output: Values of object
*
* Return:
*
* Side Effects: NONE
*/
fprintf(stderr, "Value of Sock: %d\n", sock);
return(self);
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.