HelloC/tcp.c
2023-11-25 19:27:12 +01:00

115 lines
3.1 KiB
C

#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#define SERVER "devloop.de"
#define PORT 25
#define RECEIVE_BUFFER 256
char* copyNtrim(char *str) {
char *ret = strdup(str);
for (int i = strlen(ret); i >= 0; i--) {
if (ret[i] == '\r' || ret[i] == '\n') {
ret[i] = '\0';
}
}
return ret;
}
void sendMessage(int sock, char *msg) {
int sendBytes = send(sock, msg, strlen(msg), 0);
if (sendBytes >= 0) {
printf("Send %d bytes to %s:%d: %s\n", sendBytes, SERVER, PORT, copyNtrim(msg));
} else {
fprintf(stderr, "Failed to send message to %s:%d (%d): %s", SERVER, PORT, errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
void receiveMessage(int sock, char *buf, int bufLen) {
int recvBytes = recv(sock, buf, bufLen, 0);
if (recvBytes >= 0) {
printf("Received %d bytes from %s: %s\n", recvBytes, SERVER, copyNtrim(buf));
} else {
fprintf(stderr, "Error receiving data from %s (%d): %s", SERVER, errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
struct sockaddr_in6* lookup(char *host) {
int err;
// lookup IPv6 address
struct addrinfo hints;
struct addrinfo *serverAddrs;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
err = getaddrinfo(host, NULL, &hints, &serverAddrs);
if (err) {
fprintf(stderr, "Error looking up host %s (%d): %s\n", host, err, gai_strerror(err));
exit(EXIT_FAILURE);
}
// print out IPv6 addresses
struct addrinfo *serverAddr;
struct sockaddr_in6 *serverAddr_in6;
for (serverAddr = serverAddrs; serverAddr != NULL; serverAddr = serverAddr->ai_next) {
serverAddr_in6 = (struct sockaddr_in6 *)serverAddr->ai_addr;
unsigned char buf[sizeof(struct in6_addr)];
char serverAddr_str[INET6_ADDRSTRLEN];
printf("IPv6 of %s: %s\n", host, inet_ntop(AF_INET6, &serverAddr_in6->sin6_addr, serverAddr_str, INET6_ADDRSTRLEN));
}
return serverAddr_in6;
}
int connectTo(char *host, int port) {
int err;
// socket
int sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock == -1) {
fprintf(stderr, "Error creating socket (%d): %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
struct sockaddr_in6 *serverAddr_in6 = lookup(host);
// connect last IPv6 address
serverAddr_in6->sin6_port = htons(port);
err = connect(sock, (struct sockaddr *)serverAddr_in6, sizeof(*serverAddr_in6));
if (err) {
fprintf(stderr, "Error connecting %s:%d (%d): %s\n", host, port, err, gai_strerror(err));
exit(EXIT_FAILURE);
}
return sock;
}
int main() {
char buf[RECEIVE_BUFFER];
// connect
int sock = connectTo(SERVER, PORT);
// chat
receiveMessage(sock, buf, RECEIVE_BUFFER);
sendMessage(sock, "HELO tuxic.dyndns.devloop.de\r\n");
receiveMessage(sock, buf, RECEIVE_BUFFER);
sendMessage(sock, "QUIT\r\n");
receiveMessage(sock, buf, RECEIVE_BUFFER);
// end session
close(sock);
exit(EXIT_SUCCESS);
}