0% found this document useful (0 votes)
15 views11 pages

C TCP Socket Programming Examples

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views11 pages

C TCP Socket Programming Examples

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Network Programming Lab

1. Write a C program to implement daytime client/server program using TCP sockets

Client1.c

#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int sockfd;
char buff[1024];
struct sockaddr_in servaddr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
read(sockfd, buff, sizeof(buff));
fputs(buff, stdout);
close(sockfd);
}
Server1.c
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int sockfd, connfd;
struct sockaddr_in servaddr, cliaddr;
char buff[1024];
time_t ticks;
socklen_t len = sizeof(cliaddr);
// Create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// Set up server address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(atoi(argv[1]));
// Bind and listen
bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
listen(sockfd, 1);
printf("Server is waiting for connection at port %s...\n", argv[1]);
// Accept one client
connfd = accept(sockfd, (struct sockaddr*)&cliaddr, &len);
// Send current time
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
write(connfd, buff, strlen(buff));
// Close connections
close(connfd);
close(sockfd);
return 0;
}
2. Write a TCP client/server program in which client sends three numbers to the server in a single
message. Server returns sum, difference and product as a result single message. Client program
should print the results appropriately

Client.c

#include <stdio.h>

#include <netinet/in.h>

#include <unistd.h>

int main() {

int sock, nums[3], results[3];

struct sockaddr_in server_addr;

sock = socket(AF_INET, SOCK_STREAM, 0);

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = INADDR_ANY;

connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));

printf("Enter 3 numbers: ");

scanf("%d %d %d", &nums[0], &nums[1], &nums[2]);

write(sock, nums, sizeof(nums));

read(sock, results, sizeof(results));

printf("Sum = %d\n", results[0]);

printf("Difference = %d\n", results[1]);

printf("Product = %d\n", results[2]);

close(sock);

return 0;

Server.c

#include <stdio.h>

#include <netinet/in.h>

#include <unistd.h>

int main() {

int server_sock, client_sock, nums[3], sum, diff, prod;

struct sockaddr_in server_addr;

socklen_t addr_size;

server_sock = socket(AF_INET, SOCK_STREAM, 0);

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(8080);

server_addr.sin_addr.s_addr = INADDR_ANY;

bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr));

listen(server_sock, 5);

printf("Server is waiting for connection...\n");

addr_size = sizeof(server_addr);

client_sock = accept(server_sock, (struct sockaddr*)&server_addr, &addr_size);

printf("Client connected.\n");

read(client_sock, nums, sizeof(nums));

sum = nums[0] + nums[1] + nums[2];


diff = nums[0] - nums[1] - nums[2];

prod = nums[0] * nums[1] * nums[2];

int results[3] = {sum, diff, prod};

write(client_sock, results, sizeof(results));

printf("Calculation done. Sent to client.\n");

close(client_sock);

close(server_sock);

return 0;

3. Write a C program that prints the IP layer and TCP layer socket options in a separate file

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main() { int sockfd;

int optval;
socklen_t optlen = sizeof(optval);
FILE *fp;
// Create TCP socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// Open file for writing
fp = fopen("socket_options.txt", "w");
if (!fp) {
perror("Failed to open output file");
close(sockfd);
exit(EXIT_FAILURE);
}
// IP layer option: IP_TTL
if (getsockopt(sockfd, IPPROTO_IP, IP_TTL, &optval, &optlen) == 0) {
fprintf(fp, "IP_TTL: %d\n", optval);
} else {
perror("getsockopt IP_TTL failed");
}
// IP layer option: IP_TOS
if (getsockopt(sockfd, IPPROTO_IP, IP_TOS, &optval, &optlen) == 0) {
fprintf(fp, "IP_TOS: %d\n", optval);
} else {
perror("getsockopt IP_TOS failed");
}
// TCP layer option: TCP_NODELAY

if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, &optlen) == 0) {

fprintf(fp, "TCP_NODELAY: %d\n", optval);


} else {
perror("getsockopt TCP_NODELAY failed");
}
// TCP layer option: TCP_MAXSEG
if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &optval, &optlen) == 0) {
fprintf(fp, "TCP_MAXSEG: %d\n", optval);
} else {
perror("getsockopt TCP_MAXSEG failed");
}
// TCP_KEEPIDLE
if (getsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, &optlen) == 0) {
fprintf(fp, "TCP_KEEPIDLE: %d\n", optval);
} else {
perror("getsockopt TCP_KEEPIDLE failed");
}
// TCP_KEEPCNT
if (getsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &optval, &optlen) == 0) {
fprintf(fp, "TCP_KEEPCNT: %d\n", optval);
} else {
perror("getsockopt TCP_KEEPCNT failed");
}
// TCP_KEEPINTVL
if (getsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, &optlen) == 0) {
fprintf(fp, "TCP_KEEPINTVL: %d\n", optval);
} else {
perror("getsockopt TCP_KEEPINTVL failed");
}
if (getsockopt(sockfd, IPPROTO_TCP, TCP_WINDOW_CLAMP, &optval, &optlen) == 0) {
fprintf(fp, "TCP_WINDOW_CLAMP: %d\n", optval);
} else {
perror("getsockopt TCP_WINDOW_CLAMP failed");
}
fclose(fp);
close(sockfd);
return 0;
}
4. Exercises on Socket Programming using C and Java

Java program:

[Link]:

import [Link].*;
import [Link].*;
public class ImageServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
[Link]("Waiting for client...");
Socket client = [Link]();
[Link]("Client connected! Sending image...");
try (
FileInputStream in = new FileInputStream("[Link]");
OutputStream out = [Link]()
){
byte[] buffer = new byte[1024];
int n;
while ((n = [Link](buffer)) != -1)
[Link](buffer, 0, n);
}
[Link]("Image sent.");
[Link](); [Link]();
}
}
Commands to run:
gedit [Link]
javac [Link]
java ImageServer
ImageClient:
import [Link].*;
import [Link].*;
public class ImageClient {
public static void main(String[] args) {
try (
Socket socket = new Socket("[Link]", 8080);
InputStream in = [Link]();
FileOutputStream out = new FileOutputStream("[Link]")
){
[Link]("Receiving image...");
byte[] buffer = new byte[1024];
int n;
while ((n = [Link](buffer)) != -1)
[Link](buffer, 0, n);
[Link]("Saved as '[Link]'.");
} catch (IOException e) {
[Link]("error " + [Link]());
}
}
}
C program:
Server
#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
int main() {
int s = socket(AF_INET, SOCK_STREAM, 0), c;
struct sockaddr_in addr = {AF_INET, htons(8080), INADDR_ANY};
bind(s, (void*)&addr, sizeof(addr));
listen(s, 1);
printf("Server is waiting for client...\n");
c = accept(s, 0, 0);
printf("Client connected! Sending image...\n");
int img = open("[Link]", O_RDONLY);
if (img < 0) {
perror("Failed to open [Link]");
return 1;
}
char buf[1024];
int n;
while ((n = read(img, buf, sizeof(buf))) > 0)
send(c, buf, n, 0);
printf("Image sent successfully.\n");
close(img); close(c); close(s);
return 0;
}
Client:
#include <stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
int main() {
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr = {AF_INET, htons(8080)};
inet_pton(AF_INET, "[Link]", &addr.sin_addr);
connect(s, (void*)&addr, sizeof(addr));
printf("Connected to server. Receiving image...\n");
int out = open("[Link]", O_CREAT | O_WRONLY, 0666);
char buf[1024];
int n;
while ((n = recv(s, buf, sizeof(buf), 0)) > 0)
write(out, buf, n);
printf("Image received and saved as '[Link]'.\n");
close(out); close(s);
return 0;
}
Note: Save a file as [Link] in the desktop.
6. Comparison of TCP/IP, Socket, Pipes. Analyse which is the best

Client6.c

// socket_client.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <netinet/in.h>

int main() {

int sockfd;

struct sockaddr_in addr;

char *msg = "Hello from client";

sockfd = socket(AF_INET, SOCK_STREAM, 0);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = INADDR_ANY;

addr.sin_port = htons(8888);

connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));

write(sockfd, msg, strlen(msg) + 1);

close(sockfd);

return 0;

}
gcc socket_server.c -o server

gcc socket_client.c -o client (compile two programs)

server6.c

//Socket Example (Local TCP server-client)

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <netinet/in.h>

int main() {

int server_fd, client_fd;

struct sockaddr_in addr;

char buffer[1024];

server_fd = socket(AF_INET, SOCK_STREAM, 0);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = INADDR_ANY;

addr.sin_port = htons(8888);

bind(server_fd, (struct sockaddr *)&addr, sizeof(addr));

listen(server_fd, 1);

printf("Server listening on port 8888...\n");

client_fd = accept(server_fd, NULL, NULL);

read(client_fd, buffer, sizeof(buffer));

printf("Server received: %s\n", buffer);

close(client_fd);

close(server_fd);

return 0;

Pipe6.c

// Pipe Example (Parent to Child Communication)

#include <stdio.h>

#include <unistd.h>

#include <string.h>
int main() {

int fd[2];

pipe(fd);

if (fork() == 0) {

// Child process

close(fd[1]); // Close write end

char buffer[100];

read(fd[0], buffer, sizeof(buffer));

printf("Child received: %s\n", buffer);

close(fd[0]);

} else {

// Parent process

close(fd[0]); // Close read end

char *msg = "Hello from parent";

write(fd[1], msg, strlen(msg) + 1);

close(fd[1]);

return 0;

Common questions

Powered by AI

The TCP client sends three integers in a single message to the server. The server reads these values into an integer array. The server then calculates the sum, difference, and product of these three numbers. These results are stored in another integer array, which is sent back to the client. The client receives this data, extracts the results, and prints the sum, difference, and product as the final output .

Socket options related to the IP layer that can be retrieved include `IP_TTL` for the time-to-live value and `IP_TOS` for the type of service. For the TCP layer, options include `TCP_NODELAY` for disabling Nagle's algorithm, `TCP_MAXSEG` for maximum segment size, `TCP_KEEPIDLE` for the time before starting keepalives, `TCP_KEEPCNT` for the number of keepalive probes, `TCP_KEEPINTVL` for the interval between keepalive probes, and `TCP_WINDOW_CLAMP` for setting the TCP receive window size. These options are retrieved using the `getsockopt()` function and written to a file .

The C client program first establishes a connection to the server using a TCP socket. Upon connection, the client program prepares to receive image data by opening a file in write mode using `open()`. It reads the image data in chunks from the socket using the `recv()` function and writes each chunk to the file using the `write()` function. This loop continues until all data is received and written, concluding by closing the file to ensure all data is correctly saved and resources are released .

The `bind()` function associates a socket with a specific local IP address and port number, thus specifying where on the network the server will listen for incoming connections. This step is crucial for any server as it determines the access point for clients. The `listen()` function follows `bind()`, placing the socket in a passive mode to accept incoming connection requests. This function specifies a queue limit for incoming connection requests, indicating the server is ready to handle client connections. Both functions work in tandem: `bind()` sets the endpoint, while `listen()` initiates the waiting process for connections .

The Java ImageServer program first creates a `ServerSocket` to listen on a specific port. Upon accepting a client connection, it opens a `FileInputStream` to read the image file in chunks into a buffer. These chunks are then written to the client's `OutputStream` repeatedly until the entire file is sent. This loop continues until `read()` returns -1, indicating the end of the file, ensuring the entire file is transmitted. Finally, the streams and the socket are closed to release resources .

The `close()` function is critical as it frees up the resources associated with the socket, both on the client and server sides. If neglected, it can lead to resource leaks where operating system resources (file descriptors and network ports) are not released after use, potentially exhausting these resources and causing errors in socket creation or connection acceptance. Additionally, not closing sockets properly can lead to incomplete data transmission and may not release network-channel bandwidth, which can affect network performance and application stability .

First, a socket is created using the `socket()` function with parameters `AF_INET` for IPv4 and `SOCK_STREAM` for a TCP connection. Next, the server's address structure is initialized, specifying `AF_INET` in the `sin_family` field and setting `sin_addr.s_addr` to `INADDR_ANY` for binding to all interfaces. The `sin_port` field is set using `htons()` to ensure proper byte order of the port number. The socket is then bound to this address using the `bind()` function. Finally, the `listen()` function is called to put the socket into a listening state to accept incoming connections .

Pipes provide a unidirectional communication channel and are typically used for parent-child process communication on the same machine. They do not require creating server/client socket pairs and are simpler, but limited to local communication. Sockets, however, support bidirectional communication and can be used for network communication between processes on different machines. Sockets require setting up network protocols (like TCP/UDP), making them more complex but versatile compared to pipes. While pipes have lower overhead, sockets offer wider use-cases, including internet-based communication, with added complexity and resource usage .

The `inet_pton()` function is used to convert a human-readable IP address in standard text form (IPv4 or IPv6) to its binary form used within network programs. This conversion is essential to pass the structured binary IP address to low-level socket functions for establishing a connection, as these functions do not work with textual IP representations. Using `inet_pton()` ensures proper interpretation and validation of the IP address format, reducing errors in network connections .

The sequence starts with creating a socket using `socket()`, specifying `SOCK_STREAM` for TCP. The `bind()` call associates the socket with an IP address and port. The `listen()` call then marks the socket as receptive to incoming connections. Following this, `accept()` is used to actually accept an incoming client connection, producing a new socket for communication with that specific client. `read()` or `recv()` handles incoming data, while `write()` or `send()` outputs data to the client. Finally, `close()` is called to release resources for each socket when done. Each call serves a distinct role from initialization to communication and connection termination .

You might also like