Computer Organization: Networks & Remote Communication
Week 13
Today’s Goals
❖ Networking is a very common programming feature
▪ You will likely have to create a program that will read/write over the network at some point in your career
❖ We want to give you a basic, high-level understanding of how networks work before you use them
▪ Lecture will be more “story-like;” we will purposefully skip over most of the details, but hopefully you will learn something new about the Internet today!
❖ Reading
Networking Essentials: TCP/UDP & Sockets
TCP vs UDP: Core Differences
TCP (Transmission Control Protocol):
- Connection-oriented (3-way handshake)
- Reliable, ordered, byte-stream
- Uses congestion control & acknowledgments
- Good for web, SSH, email
UDP (User Datagram Protocol):
- Connectionless, no handshake
- Unreliable, unordered datagrams
- Lower latency, minimal overhead
- Good for DNS, VoIP, gaming
Code: Creating TCP vs UDP Sockets
// TCP socket
int tcp_sock = socket(AF_INET, SOCK_STREAM, 0);
// UDP socket
int udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
Sockets as File Descriptors
In Unix, EVERYTHING is a file descriptor:
- socket() returns an int fd
- read(), write(), close() work on sockets too
Example:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
write(sockfd, "hello", 5); // just like a file
Socket Lifecycle
Server Side:
1. socket()
2. bind()
3. listen()
4. accept()
Client Side:
1. socket()
2. connect()
Code: Minimal TCP Server
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(8080);
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sockfd, 5);
int client = accept(sockfd, NULL, NULL);
write(client, "Hello!", 6);
Code: Minimal TCP Client
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr);
connect(sockfd, (struct sockaddr*)&server, sizeof(server));
char buf[100];
read(sockfd, buf, 100);
printf("%s", buf);
OS Abstractions in Networking
OS abstracts hardware → uniform API:
- File descriptors unify files, pipes, sockets
- Kernel manages TCP state machine
- Buffers, queues, retransmissions hidden under API
- select(), poll(), epoll() unify I/O waiting
In-Class Exercise: Hostname Lookup in C
Networks & Remote Communication
Exercise Instructions
Write a C program that:
- Takes a hostname from the user (scanf)
- Uses gethostbyname() to resolve its IP
- Prints the IP address
Bonus:
- Try connecting to port 80
- Print "Connected!" if successful
Solution Code (Part 1)
…#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main() {
char hostname[256];
printf("Enter a hostname: ");
scanf("%255s", hostname);
struct hostent *host = gethostbyname(hostname);
if (host == NULL) {
fprintf(stderr, "Error: Could not resolve hostname.\n");
return 1;
}
Solution Code (Part 2)
struct in_addr **addr_list = (struct in_addr **)host->h_addr_list;
printf("IP Address: %s\n", inet_ntoa(*addr_list[0]));
int sockfd;
struct sockaddr_in server_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80);
server_addr.sin_addr = *addr_list[0];
Solution Code (Part 3)
if (connect(sockfd, (struct sockaddr *)&server_addr,
sizeof(server_addr)) == 0) {
printf("Connected!\n");
} else {
perror("connect");
printf("Could not connect.\n");
}
close(sockfd);
return 0;
}