Part 2 - TCP Client
Once we have a process listening at a TCP port, we can send a message to the server with a client process.
The client process will need to
- create a socket with the same
socket()and get thefd, same as the server - initiate and establish connection with
connect() - write data to the socket after
connect()withwrite() - retrieve the server’s response with
read()
Connecting to a server socket
We need to connect the client socket to the destination using connect(2).
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
We have encountered the sockaddr type before, we will use the sockaddr_in type for internet socket.
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(PORT);
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("Failed to connnect to server socket");
return 1;
};
Socket I/O
After connecting to the server, we can do read() and write() on the socket. For now, we will be using a 1024 (1kb) buffer.
#define BUFFER_SIZE 1024
// hard coded data for now
char * data = "(hard coded) Hi!";
if (write(sockfd, data, strlen(data)) < 0) {
perror("failed to write data");
return 1;
}
log_with_time("wrote data (%db) to server", strlen(data));
char * recv_data[BUFFER_SIZE];
if (read(sockfd, recv_data, BUFFER_SIZE) < 0) {
perror("failed to read server response");
}
log_with_time("server response:%s", recv_data);
The final client program will be (the log.h file is in the previous document)
#define PORT 8080
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "log.h"
#define BUFFER_SIZE 1024
int main() {
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 6);
if (sockfd == -1) {
perror("Error opening socket");
return 1;
}
log_with_time("openned socket with fd:%d", sockfd);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(PORT);
if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("Failed to connnect to server socket");
return 1;
};
// hard coded data for now
char * data = "(hard coded) Hi!";
if (write(sockfd, data, strlen(data)) < 0) {
perror("failed to write data");
return 1;
}
log_with_time("wrote data (%db) to server", strlen(data));
char * recv_data[BUFFER_SIZE];
if (read(sockfd, recv_data, BUFFER_SIZE) < 0) {
perror("failed to read server response");
}
log_with_time("server response:%s", recv_data);
return 0;
}