/* TCP Example code by Kien Pham (Heavily documented to help others understand.) This code is now in Public Domain. Look ma, I did this all by myself. */ #include // Include these for socket(), connect(), bind(), etc. #include #include // Include this for getprotobyname() #include // Include this for memset() #include // Include this for htonl(), htons(), etc. #include #define PORT 2000 void server() { // Variables for the server component of the application. int file_descriptor; // File descriptor that represents the server socket. struct sockaddr_in server_address; // Really only contains the port we want to listen on. int inbound_connection; // File descriptor that represents the socket of the inbound connection. struct sockaddr_in inbound_address; // Address of the inbound connection. int inbound_address_size; // Size of the structure for the inbound connection. unsigned char *address_holder; // Pointer to simplify the extraction of IP addresses. char message[]="Hiya client, it's me the server."; // Constant string to send to the client. char buffer[256]; // Buffer to hold incoming data from the client. // Code for the server component begins here. file_descriptor=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Allocate a TCP socket for the internet. if (file_descriptor<0) // Check to see if there was a failure in allocation. { perror("Server: socket()"); return; } memset((void*)&server_address, 0, sizeof(server_address)); // Clear the structure used to store the port and address that we want to listen on. server_address.sin_port=htons(PORT); // Put port we want to listen on here. Take care to convert from host to network endian!!! server_address.sin_family=AF_INET; // Don't ask. server_address.sin_addr.s_addr=htonl(INADDR_ANY); // Address of the local server goes here. We put INADDR_ANY constant here to say we want to listen on all addresses on hosts with multiple ip addresses. Take care to convert from host endian to network endian!!!! if (bind(file_descriptor, (struct sockaddr*)&server_address, sizeof(server_address))<0) // Ok. We setup our structure. Now we tell the OS to do it. { perror("Server: bind()"); return; } if (listen(file_descriptor, 5)<0) // Tell the OS to start listening on our port and local address for clients that want to connect. { perror("Server: listen()"); return; } memset((void*)&inbound_address, 0, sizeof(inbound_address)); inbound_address.sin_family=AF_INET; inbound_address_size=sizeof(inbound_address); // Make sure you do this, or the inbound_address will not be filled with information about the incomming address. inbound_connection=accept(file_descriptor, (struct sockaddr*)&inbound_address, &inbound_address_size); // Grab the first socket that represents the client that has connected. If none yet, block and wait till somebody does. if (inbound_connection<0) { perror("accept()"); return; } address_holder=(unsigned char*)&inbound_address.sin_addr.s_addr; // Save ourselves a call to the OS to convert. printf("Server: Got a connection from %d.%d.%d.%d\n", address_holder[0], address_holder[1], address_holder[2], address_holder[3]); printf("Server: The inbound sockaddr structure is %d bytes long.\n", inbound_address_size); if (write(inbound_connection, message, sizeof(message))<0) // Write the message to the client. { perror("Server: write()"); return; } if (read(inbound_connection, buffer, 255)<0) // Read from the client. { perror("Server: read()"); return; } printf("Server: Got this message from the client: %s\n", buffer); // Print results. close(inbound_connection); // Tell the OS to clean up and free resources that we have used. close(file_descriptor); } void client() { // Variables for the client component of the application. int file_descriptor; // File descriptor that represents the client socket. struct protoent *protocol_information; // Structure pointer to gain the address of the structure passed back from getprotobyname(). The structure wil contain all the information about a particular protocol. struct sockaddr_in target_host_address; // Structure to hold the target address of the connection. (The i.p. address and port of the host we want to connect to.) unsigned char *address_holder; // Pointer to simplify ip address designation. char message[]="Hiya server, it's me the client."; char buffer[256]; // Code for the client component begins here. protocol_information=getprotobyname("tcp"); // This is another way to grab the protocol number. if (protocol_information==NULL) { perror("Client: getprotobyname()"); return; } file_descriptor=socket(AF_INET, SOCK_STREAM, protocol_information->p_proto); if (file_descriptor<0) { perror("Client: socket()"); return; } memset((void*)&target_host_address, 0, sizeof(target_host_address)); target_host_address.sin_family=AF_INET; target_host_address.sin_port=htons(PORT); address_holder=(unsigned char*)&target_host_address.sin_addr.s_addr; // Lazy way to put 127.0.0.1 into the address portion in the structure w/o care of the endians. address_holder[0]=127; address_holder[1]=0; address_holder[2]=0; address_holder[3]=1; if (connect(file_descriptor, (struct sockaddr*)&target_host_address, sizeof(target_host_address))<0) // 'Call' the server. { perror("Client: connect()"); return; } if (recvfrom(file_descriptor, buffer, 255, 0, NULL, NULL)<0) // Another way to read data. Equivalent to the deprecated(or will be deprecated) recv(). { perror("Client: recvfrom()"); return; } printf("Client: Got this message from the server: %s\n", buffer); if (sendto(file_descriptor, message, sizeof(message), 0, NULL, 0)<0) // Another way to send data. { perror("Client: send()"); return; } close(file_descriptor); } int main(int number_of_arguments, char *arguments[]) { // Main variables. int process_id; // Process identification number to be returned from fork(). printf("\nTCP Networking Example\n"); printf("Written by Kien Pham\n"); printf("For the Networking mini-Tutorial (http://www.tripod.com/~Xengren)\n"); process_id=fork(); // Split into two separate processes and run server in one and client in the other. if (process_id<0) { perror("fork()"); return 0; } if (process_id!=0) server(); else client(); // End of code, obviously. }