SPC 1 Network Applications Network Applications | | Socket Programming in C Socket Programming in C (Self (Self - - study and Practice) study and Practice) SPC 2 Versions of Socket APIs Versions of Socket APIs • The Berkeley Socket API Berkeley Socket API - Developed in early1980s by UCB Allows programmers to write application programs easily w/o worrying about the underlying networking details Works well for many UNIX-like OS : OpenBSD, FreeBSD, Linux, HURD (free S/W foundation, GNU project.), Chorus (Sun Microsystems), etc. • The Windows Socket Socket ( Winsock Winsock) API - Windows extension of Berkeley socket API by Microsoft A library of socket interface functions Need to import the wsock32.lib (in a 32-bit Windows environment). This library has to be linked in order to load the dynamic link library wsock32.dll at run time.) SPC 3 Winsock Layering Winsock Layering • Application programmers write to the WinSock API and link their applications with the WINSOCK.LIB import library (or WSOCK32.LIB in the case of Win32). The application can then be installed on a computer that has a WinSock TCP/IP stack, from any number of vendors, and dynamically link to the WINSOCK.DLL (or WSOCK32.DLL) provided by the vendor. Win32 WinSock Application WINSOCK32.DLL Appl. Layer OS layer SPC 4 Socket System Calls Socket System Calls Creating a socket (an endpoint) #include <sys/socket.h> #include <sys/socket.h> #include <sys/types.h> int socket(int family, int type, int protocol); • commu. domaim, identified by a Address (AF) or a Protocol (PF) name • AF_UNIX, AF_INET, AF_OSI, PF_XXX ( = AF_XXX), etc. • AF_UNIX ~ file system pathname, commu. for local UNIX machine. • AF_INET~ for Internet communication using TCP/IP • needed for socket related definitions • creates an unbounded socket & returns a file descriptor (nonneg. int.) • returns –1 in the case of a failure • needed for system defined identifiers
12
Embed
2.2 Socket programming - ntut.edu.twkwke/DC2006/socket programming in C.… · SPC 1 Network Applications | Socket Programming in C (Self-study and Practice) SPC 2 Versions of Socket
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
SPC 1
Network ApplicationsNetwork Applications
||
Socket Programming in CSocket Programming in C
(Self(Self--study and Practice)study and Practice)SPC 2
Versions of Socket APIsVersions of Socket APIs• The Berkeley Socket APIBerkeley Socket API
- Developed in early1980s by UCB Allows programmers to write application programs easily w/o worrying about the underlying networking details
Works well for many UNIX-like OS : OpenBSD, FreeBSD, Linux, HURD (free S/W foundation, GNU project.), Chorus (Sun Microsystems), etc.
• The Windows SocketSocket (WinsockWinsock) API- Windows extension of Berkeley socket API by Microsoft
A library of socket interface functions Need to import the wsock32.lib (in a 32-bit Windows environment). This library has to be linked in order to load the dynamic link library wsock32.dll at run time.)
SPC 3
Winsock LayeringWinsock Layering
• Application programmers write to the WinSock API and link their applications with the WINSOCK.LIB import library (or WSOCK32.LIBin the case of Win32). The application can then be installed on a computer that has a WinSock TCP/IP stack, from any number of vendors, and dynamically link to the WINSOCK.DLL (or WSOCK32.DLL) provided by the vendor.
Win32 WinSock Application
WINSOCK32.DLLAppl. LayerOS layer
SPC 4
Socket System CallsSocket System CallsCreating a socket (an endpoint)
#include <sys/socket.h>#include <sys/types.h>int socket(int family, int type, int protocol);
#include <sys/socket.h>#include <sys/types.h>int socket(int family, int type, int protocol);
• commu. domaim, identified by a Address (AF) or a Protocol (PF) name• AF_UNIX, AF_INET, AF_OSI, PF_XXX ( = AF_XXX), etc. • AF_UNIX ~ file system pathname, commu. for local UNIX machine.• AF_INET~ for Internet communication using TCP/IP
• needed for socket related definitions
• creates an unbounded socket & returns a file descriptor (nonneg. int.)• returns –1 in the case of a failure
• needed for system defined identifiers
SPC 5
Creating a socket (cont’d)
#include <sys/socket.h>#include <sys/types.h>int socket(int family, int type, int protocol);
#include <sys/socket.h>#include <sys/types.h>int socket(int family, int type, int protocol);
• Needed for Internet address structure:#include <netinet/in.h>
• Generic address structure for many types of sockets:
• To deal with struct sockaddr, programmers created a parallel structure: (next page)
struct sockaddr_in ("in" for "Internet".)
• This structure makes it easy to reference elements of the socket addr.SPC 8
Socket address structure: for AF_INET
struct sockaddr_in {unsigned short sin_family; // AF_INET identifiers (host order)unsigned short sin_port; // 16-bit TCP/UDP port number,
// if 0, then kernel chosenstruct in_addr sin_addr; // 32-bit IP addresschar sin_zero[8]; // Unused, using memset() to all “0”
}; //16-byte, same as struct sockaddr
struct sockaddr_in {unsigned short sin_family; // AF_INET identifiers (hosthost order)unsigned short sin_port; // 16-bit TCP/UDP port number,
// if 0, then kernel chosenstruct in_addr sin_addr; // 32-bit IP addresschar sin_zero[8]; // Unused, using memset() to all “0”
}; //16-byte, same as struct sockaddr
#include <netinet/in.h>struct in_addr{ unsigned long s_addr; // store a 32-bit IP address };
#include <netinet/in.h>struct in_addr{ unsigned long s_addr; // store a 32-bit IP address }; • Must be in
NetworkNetwork Byte Order!
• A pointer to a struct sockaddr_in can be cast to a pointer to a structsockaddr and vice-versa. So even though socket() wants a structsockaddr*, you can still use a struct sockaddr_in tocast it.
• Bind()Bind() is optional on the client side. We only care about where the remote port is. W/o calling bind(), the kernel will give a rndomlocal port # and the remote site will automatically get it in connection.
SPC 10
Data representation and byte ordering
• Big endian ~ store the high byte of an integer in the leftmost byte, while the low byte of an integer is stored in the rightmost byte (i.e., MSB first). E.g., Sun Sparc, M6800
• Little endian ~ vice versa (i.e., LSB first). E.g., i-386 PC
• Ex: The number 0x0564
0564Little endian
4650Big endian
13(high addr.)121110(low addr.)Memory address
• TCP/IP defines a machine independent standard: network byte order In a packet, the first transmitted data is the most significant bytenetwork byte order is big endian (Because big endian refers to storing the most significant byte in the lowest memory address).
leftmost rightmost
SPC 11
Byte order conversion
• unsigned long htonl(unsigned long n)~ host to network conversion of a 32-bit value (long);
• unsigned short htons(unsigned short n)~ host to network conversion of a 16-bit value (short);
• unsigned long ntohl(unsigned long n) ~ network to host conversion of a 32-bit value;
• unsigned short ntohs(unsigned short n) ~ network to host conversion of a 16-bit value.
• unsigned long htonl(unsigned long n)~ host to network conversion of a 32-bit value (long);
• unsigned short htons(unsigned short n)~ host to network conversion of a 16-bit value (short);
• unsigned long ntohl(unsigned long n) ~ network to host conversion of a 32-bit value;
• unsigned short ntohs(unsigned short n) ~ network to host conversion of a 16-bit value.
• Functions are used to convert from host to network ordering before transmission, and from network to host form after reception:
• h ~ host; n ~ network; s ~ short; l ~ long; a ~ ascii;• N.B.O. ~ network byte order
SPC 12
IP address Manipulation functions (1/3)• No need to figure them out by hand and stuff them in a long withthe « operator.
• Example: An IP address "10.12.110.57“ needed to be storedinto struct sockaddr_in ina. A programmer may do :
inet_addr() takes a host address in dotted-decimal notation and returns corresponding 32-bit IP adddressIt returns the address in Network Byte Order already.
• Also: Converting 32-bit IP address in N.B.O. to dotted-decimal notation
• Q: There is no error checking. The inet_addr() returns -1 on error. Remember : a 32-bit (unsigned)-1 in Binary representation just happens to correspond to the IP address “255.255.255.255”!
That’s the broadcast address! So, be do error checking properly.
• For CO-mode (TCP), it attempts to establish a connection to the remote destination specified by *remote_addr.
• For CL-mode (UDP), it store the server’s socket address that identifies where all datagrams are sent (no connection is made).
• local_s ~ is a local socket descriptor (e.g., client);• remote_addr ~ is a pointer to socket structure containing the
peer protocol address (e.g., server);• rmtaddr_len ~ is the length in bytes of the sockaddr address
structure.SPC 16
“connect” call synopsis:
#define PORT_NUM 1050 // Arbitrary port numberstruct sockaddr_in serv_addr; // Server Internet addressint rmt_s; // Remote socket descriptor/* Fill-in the server (remote) socket's address information and connect with the listening server */server_addr.sin_family = AF_INET; // Address family to useserver_addr.sin_port = htons(PORT_NUM); // Port num to useserver_addr.sin_addr.s_addr = inet_addr(inet_ntoa(IP address));if (connect(rmt_s,(struct sockaddr *)&serv_addr,
#define PORT_NUM 1050 // Arbitrary port numberstruct sockaddr_in serv_addr; // Server Internet addressint rmt_s; // Remote socket descriptor/* Fill-in the server (remote) socket's address information and connect with the listening server */server_addr.sin_family = AF_INET; // Address family to useserver_addr.sin_port = htons(PORT_NUM); // Port num to useserver_addr.sin_addr.s_addr = inet_addr(inet_ntoa(IP address));if (connect(rmt_s,(struct sockaddr *)&serv_addr,
• accept() returns a new socket descriptor on success or –1 on failure
• server_s ~ a bounded socket descriptor the server is listening on (i.e., the server’s socket)
• client_addr ~ filled with the client address• clntaddr_len ~ contains the length of the client address structure
SPC 19
Synopsis:
struct sockaddr_in client_addr;int server_s, client_s, clntaddr_len;...if ((client_s = accept(server_s, (struct sockaddr *)&client_addr, &clntaddr_len) < 0){ printf(accept() failed.); exit(1); }// at this stage a thread or a process can take over and handle// communication with the client
struct sockaddr_in client_addr;int server_s, client_s, clntaddr_len;...if ((client_s = accept(server_s, (struct sockaddr *)&client_addr, &clntaddr_len) < 0){ printf(accept() failed.); exit(1); }// at this stage a thread or a process can take over and handle// communication with the client
• The first queued incoming connection is accepted, and a new socket sd is created and returned. It is the socket thatthe server will use from now on to communicate with this client. (i.e., Server uses the returned (new) sd to perform data transfer.)
Once accept() being executed . . .
SPC 20
A few more to say about accept() on server . . .
• The first queued incoming connection is accepted, and a new socket sd is created and returned. It is the socket thatthe server will use from now on to communicate with this client. (i.e., Server uses the returned (new) sd to perform data transfer.)
• Concurrent server:- Multiple successful calls to connect() will result in multiple
new sockets returned.- Server can use the same server_s to accept further connectionrequest welcoming socket
- Successive calls to accept() on the same listening socket return different connected sockets. These connected sockets are multiplexed on the same port of the server by the running TCP stack functions.
SPC 21
Sending and Receiving data on a TCPTCP socket (CO)
#include <sys/socket.h>int send(int socket, const void *msg, unsigned int msg_length,
int flags);int recv(int socket, void *rcv_buff, unsigned int buff _length,
int flags);
#include <sys/socket.h>int send(int socket, const void *msg, unsigned int msg_length,
int flags);int recv(int socket, void *rcv_buff, unsigned int buff _length,
int flags);
• socket ~ the socket descrip. used to send and receive data• msg ~ the pointer to the buffer containing message to be sent/rec.• msg_length ~ the message length in bytes (pointer = address)• rcv_buff ~ a pointer to the buffer the rcved_msg should be stored• buff_length ~ The length of receiving buffer• flags ~ the type of message transmission/reception. Default = 0.
(e.g., MSG_OOB ~ requests out-of-band data.)
• Returns # of bytes of message sent/received or -1 on failure
SPC 22
Synopsis:
#include <sys/socket.h>. . . char *msg = “This is the text to be sent”;unsigned int msg_length, bytes_sent;. . .msg_length = strlen(msg);bytes_sent = send(server_s, msg, msg_length, 0);. . .
#include <sys/socket.h>. . . char *msg = “This is the text to be sent”;unsigned int msg_length, bytes_sent;. . .msg_length = strlen(msg);bytes_sent = send(server_s, msg, msg_length, 0);. . .
• send() returns the bytes # actually sent out, might < # asked to send• if byte_sent < msg_length to send the rest of the msg• if msg is small (say < 1kB or so), the send() will probably send it all in one go.
SPC 23
Sending data on a UDPUDP socket (CL mode)
#include <sys/socket.h>int sendto(int socket, const void *msg, unsigned int msg_length,
int flags, struct sockaddr *dest_addr, unsigned int addr_length);
#include <sys/socket.h>int sendto(int socket, const void *msg, unsigned int msg_length,
int flags, struct sockaddr *dest_addr, unsigned int addr_length);
• Callers of sendto() need to be informed of the to send *msg; • No guarantee on the delivery of the message
• Returns # of bytes of message sent or -1 on failure
• socket , msg, msg_length, flags are same as in the send()• dest_addr ~ points to a sockaddr structure containing the
destination address• addr_length ~ specifying the length of the sockaddr
structure pointed to by dest_addr
SPC 24
Receiving data on a UDPUDP socket (CL mode)
#include <sys/socket.h>int recvfrom(int socket, void *rcv_buff, unsigned int buff _length,
int flags, struct sockaddr *src_addr, unsigned int addr_length);
#include <sys/socket.h>int recvfrom(int socket, void *rcv_buff, unsigned int buff _length,
int flags, struct sockaddr *src_addr, unsigned int addr_length);
• Callers of recvfrom() need to distinguish between different sources sending datagram messages to the caller.
• Returns # of bytes of message received or -1 on failure
• socket, rcv_buff, buff_length, flags are same as in the recv()• src_addr ~ points to a sockaddr structure in which the sending
address to be stored (if it’s not a null pointer)• addr_length ~ specifying (regulating) the length of the sockaddr
structure pointed to by src_addr
SPC 25
Synopsis:. . . unsigned int server_s; // Server socket descriptorstruct sockaddr_in server_addr; // Server Internet addressint addr_len; // Internet address lengthchar out_buf[100]; // 100-byte output data bufferchar in_buf[100]; // 100-byte input data bufferserver_s = socket(AF_INET, SOCK_DGRAM, 0); // Create a socketserver_addr.sin_family = AF_INET; // Address family to useserver_addr.sin_port = htons(PORT_NUM); // Port num to useserver_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to usestrcpy(out_buf, Message from client1 to server1); // Assign a message to out_buf// send message to server1. The + 1 includes the end-of-string delimitersendto(server_s, out_buf, (strlen(out_buf) + 1), 0, (struct sockaddr *)&server_addr,
sizeof(server_addr));// Wait to receive a messageaddr_len = sizeof(server_addr); //should be initialized to sizeof(sturct sockaddr).recvfrom(server_s, in_buf, sizeof(in_buf), 0, (struct sockaddr *)&server_addr,
&addr_len);printf(Message received is: '%s' \n, in_buf);
. . . unsigned int server_s; // Server socket descriptorstruct sockaddr_in server_addr; // Server Internet addressint addr_len; // Internet address lengthchar out_buf[100]; // 100-byte output data bufferchar in_buf[100]; // 100-byte input data bufferserver_s = socket(AF_INET, SOCK_DGRAM, 0); // Create a socketserver_addr.sin_family = AF_INET; // Address family to useserver_addr.sin_port = htons(PORT_NUM); // Port num to useserver_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to usestrcpy(out_buf, Message from client1 to server1); // Assign a message to out_buf// send message to server1. The + 1 includes the end-of-string delimitersendto(server_s, out_buf, (strlen(out_buf) + 1), 0, (struct sockaddr *)&server_addr,
sizeof(server_addr));// Wait to receive a messageaddr_len = sizeof(server_addr); //should be initialized to sizeof(sturct sockaddr).recvfrom(server_s, in_buf, sizeof(in_buf), 0, (struct sockaddr *)&server_addr,
&addr_len);printf(Message received is: '%s' \n, in_buf);
• terminates a connection and return/free system resources to the OS• close() returns 0 on success or -1 on failure
// Create a socket/* - AF_INET is Address Family Internet and
SOCK_DGRAM is datagram */server_s = socket(AF_INET, SOCK_DGRAM, 0);. . .close(server_s);
// Create a socket/* - AF_INET is Address Family Internet and
SOCK_DGRAM is datagram */server_s = socket(AF_INET, SOCK_DGRAM, 0);. . .close(server_s);
Synopsis:
SPC 27
Running a socket program under Windows (WINSOCK)
#define WIN // WIN for Winsock #include <stdio.h> // Needed for printf()#include <stdlib.h> // Needed for exit()#include <string.h> // Needed for memcpy() and strcpy()#ifdef WIN
#include <windows.h> // Needed for all Winsock functions#endif. . .void main(int argc, char *argv[]) {#ifdef WIN
WORD wVersionRequested = MAKEWORD(1,1); // Stuff for WSA functionsWSADATA wsaData; // Stuff for WSA functions
#define WIN // WIN for Winsock #include <stdio.h> // Needed for printf()#include <stdlib.h> // Needed for exit()#include <string.h> // Needed for memcpy() and strcpy()#ifdef WIN
#include <windows.h> // Needed for all Winsock functions#endif. . .void main(int argc, char *argv[]) {#ifdef WIN
WORD wVersionRequested = MAKEWORD(1,1); // Stuff for WSA functionsWSADATA wsaData; // Stuff for WSA functions
• Need initialization, and different include and definition files
SPC 28
host name (information) defined in <netdb.h>
#define struct hostent {char *h_name; // (pointer to) official name of hostchar **h_aliases; // (pointer to) list of alias names for this host;
// terminated by a null (h_aliases[0] 1st one)int h_addrtype; // host address type, e.g. AF_INETint h_length; // length of address structure (always = 4)char **h_addr_list; // list of addresses in network byte order
// terminated by a null };#define h_addr h_addr_list[0] // the first entry holding Internet addr.
#define struct hostent {char *h_name; // (pointer to) official name of hostchar **h_aliases; // (pointer to) list of alias names for this host;
// terminated by a null (h_aliases[0] 1st one)int h_addrtype; // host address type, e.g. AF_INETint h_length; // length of address structure (always = 4)char **h_addr_list; // list of addresses in network byte order
// terminated by a null };#define h_addr h_addr_list[0] // the first entry holding Internet addr.
struct hostent *gethostbyaddr(char *addr, int len, int type);
• returns a pointer to struct hostent on success or NULL(0) on error
• a pointer to an array that contains a host (IP) address
• give the address length in bytes (4 for IP)
• address type (AF_INET for IP)
SPC 32
Send/Receive data using Write/Read Functions
#include <sys/socket.h>int write(int socket, &char wrt_buf, int buf_len);Int read(int socket, &char red_buf, int buf_len)
#include <sys/socket.h>int write(int socket, &char wrt_buf, int buf_len);Int read(int socket, &char red_buf, int buf_len)
• socket ~ the socket descrip. used to send and receive data• wrt_buf ~ the address of a buffer containing data• red_buff ~ a pointer to an array of characters to hold the data• buf_len ~ the number of bytes in the buffer array
• Returns # of bytes of message sent/received or -1 on failure• read() returns 0 if it detects an end-of-file on the socket
SPC 33
Example: TCP Echo Server/* A simple echo server using TCP */#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>
#define SERVER_TCP_PORT 3000#define BUFLEN 256
int main(int argc, char **argv){
int n, bytes_to_read;int sd, new_sd, client_len, port;struct sockaddr_in server, client;char *bp, buf[BUFLEN];
printf("Data is corrupted\n");close(sd);return(0);
} /*end of main() */
SPC 37
Exercise: Executing a Remote .exe Program#include <stdio.h> // Needed for printf()#include <stdlib.h> // Needed for exit()#include <string.h> // Needed for memcpy() and strcpy()#include <windows.h> // Needed for Sleep() and Winsock stuff#include <fcntl.h> // Needed for file i/o constants#include <sys\stat.h> // Needed for file i/o constants#include <io.h> // Needed for open(), close(), and eof()#define PORT_NUM 1050 // Arbitrary port number for the server#define MAX_LISTEN 1 // Maximum number of listens to queue#define SIZE 256 // Size in bytes of transfer buffervoid main(int argc, char *argv[]){WORD wVersionRequested = MAKEWORD(1,1); // WSA functionsWSADATA wsaData; // Winsock API data structureunsigned int remote_s; // Remote socket descriptorstruct sockaddr_in remote_addr; // Remote Internet addressstruct sockaddr_in server_addr; // Server Internet addressunsigned char bin_buf[SIZE]; // Buffer for file tranferunsigned int fh; // File handleunsigned int length; // Length of buffers transferredstruct hostent *host; // Structure for gethostbyname()struct in_addr address; // Structure for Internet addresschar host_name[256]; // String for host nameint addr_len; // Internet address lengthunsigned int local_s; // Local socket descriptorstruct sockaddr_in local_addr; // Local Internet addressstruct in_addr remote_ip_addr; // Remote IP address// Check if number of command line arguments is validif (argc !=4){printf( *** ERROR - Must be 'local (host) (exefile) (outfile)' \n);printf( where host is the hostname *or* IP address \n);
Local site Local site programprogram
printf( of the host running remote.c, exefile is the \n);printf( name of the file to be remotely run, and \n);printf( outfile is the name of the local output file. \n);exit(1);}// Initialization of winsockWSAStartup(wVersionRequested, &wsaData);// Copy host name into host_namestrcpy(host_name, argv[1]);// Do a gethostbyname()host = gethostbyname(argv[1]);if (host == NULL){printf( *** ERROR - IP address for '%s' not be found \n, host_name);exit(1);}// Copy the four-byte client IP address into an IP address structurememcpy(&address, host->h_addr, 4);// Create a socket for remoteremote_s = socket(AF_INET, SOCK_STREAM, 0);// Fill-in the server (remote) socket's address information and connect// with the listening server.server_addr.sin_family = AF_INET; // Address family to useserver_addr.sin_port = htons(PORT_NUM); // Port num to useserver_addr.sin_addr.s_addr = inet_addr(inet_ntoa(address)); // IP addressconnect(remote_s, (struct sockaddr *)&server_addr, sizeof(server_addr));// Open and read *.exe fileif((fh = open(argv[2], O_RDONLY | O_BINARY, S_IREAD | S_IWRITE)) == -1){printf( ERROR - Unable to open file '%s'\n, argv[2]);exit(1);}
windows console
SPC 38
// Output message stating sending executable fileprintf(Sending '%s' to remote server on '%s' \n, argv[2], argv[1]);// Send *.exe file to remotewhile(!eof(fh)){length = read(fh, bin_buf, SIZE);send(remote_s, bin_buf, length, 0);}// Close the *.exe file that was sent to the server (remote)close(fh);// Close the socketclosesocket(remote_s);// Cleanup WinsockWSACleanup();// Output message stating remote is executingprintf( '%s' is executing on remote server \n, argv[2]);// Delay to allow everything to clean-upSleep(100);// Initialization of winsockWSAStartup(wVersionRequested, &wsaData);// Create a new socket to receive output file from remote serverlocal_s = socket(AF_INET, SOCK_STREAM, 0);// Fill-in the socket's address information and bind the socketlocal_addr.sin_family = AF_INET; // Address family to uselocal_addr.sin_port = htons(PORT_NUM); // Port num to uselocal_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Listen on any IP addrbind(local_s, (struct sockaddr *)&local_addr, sizeof(local_addr));// Listen for connections (queueing up to MAX_LISTEN)listen(local_s, MAX_LISTEN);// Accept a connection, the accept will block and then return with// remote_addr filled in.addr_len = sizeof(remote_addr);remote_s = accept(local_s, (struct sockaddr*)&remote_addr, &addr_len);
• Local site program (cont’d)
// Copy the four-byte client IP address into an IP address structurememcpy(&remote_ip_addr, &remote_addr.sin_addr.s_addr, 4);// Create and open the output file for writingif ((fh=open(argv[3], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,S_IREAD | S_IWRITE)) == -1){printf( *** ERROR - Unable to open '%s'\n, argv[3]);exit(1);}// Receive output file from serverlength = SIZE;while(length > 0){length = recv(remote_s, bin_buf, SIZE, 0);write(fh, bin_buf, length);}// Close output file that was received from the remoteclose(fh);// Close the socketsclosesocket(local_s);closesocket(remote_s);// Output final status messageprintf(Execution of '%s' and transfer of output to '%s' done! \n,argv[2], argv[3]);// Cleanup WinsockWSACleanup();}
SPC 39
Exercise: Executing a Remote .exe ProgramRemote site programRemote site program#include <stdio.h> // Needed for printf()
#include <stdlib.h> // Needed for exit()#include <string.h> // Needed for memcpy() and strcpy()#include <windows.h> // Needed for Sleep() and Winsock stuff#include <fcntl.h> // Needed for file i/o constants#include <sys\stat.h> // Needed for file i/o constants#include <io.h> // Needed for open(), close(), and eof()#define PORT_NUM 1050 // Arbitrary port number for the server#define MAX_LISTEN 1 // Maximum number of listens to queue#define IN_FILE run.exe // Name given to transferred *.exe file#define TEXT_FILE output // Name of output file for stdout#define SIZE 256 // Size in bytes of transfer buffervoid main(void){WORD wVersionRequested = MAKEWORD(1,1); // WSA functionsWSADATA wsaData; // WSA functionsunsigned int remote_s; // Remote socket descriptorstruct sockaddr_in remote_addr; // Remote Internet addressstruct sockaddr_in server_addr; // Server Internet addressunsigned int local_s; // Local socket descriptorstruct sockaddr_in local_addr; // Local Internet addressstruct in_addr local_ip_addr; // Local IP addressint addr_len; // Internet address lengthunsigned char bin_buf[SIZE]; // File transfer bufferunsigned int fh; // File handleunsigned int length; // Length of transf. buffers// Do foreverwhile(1){// Winsock initializationWSAStartup(wVersionRequested, &wsaData);
// Create a socket
remote_s = socket(AF_INET, SOCK_STREAM, 0);
// Fill-in my socket's address information and bind the socket
remote_addr.sin_family = AF_INET; // Address family to use
remote_addr.sin_port = htons(PORT_NUM); // Port number to use
remote_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Listen on any IP addr
Remote site program (contRemote site program (cont’’d)d)connect(local_s, (struct sockaddr *)&server_addr, sizeof(server_addr));// Print message acknowledging transfer of output to clientprintf( Sending output file to local host \n);// Open output file to send to clientif((fh = open(TEXT_FILE, O_RDONLY | O_BINARY, S_IREAD |S_IWRITE)) == -1){printf( *** ERROR - unable to open output file \n);exit(1);}// Send output file to clientwhile(!eof(fh)){length = read(fh, bin_buf, SIZE);send(local_s, bin_buf, length, 0);}// Close output fileclose(fh);// Close socketsclosesocket(remote_s);closesocket(local_s);// Cleanup WinsockWSACleanup();// Delay to allow everything to clean-upSleep(100);}}
•• Assignment: Fix the problems if any and Assignment: Fix the problems if any and get it running on your Windows OS.get it running on your Windows OS.
SPC 41
IP Multicast Example - Linux• multicast server : simple multicast server that prints received messages.
/* check if dest address is multicast */if(!IN_MULTICAST(ntohl(servAddr.sin_addr.s_addr))) {printf("%s : given address '%s' is not multicast \n",argv[0],