Dieses Programm zeigt, wie man unter Windows einen konsolenbasierten Client schreiben kann. Der Client soll einfach alles, das auf der Konsole kommt, aufs Netzwerk schreiben, und umgekehrt.
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winsock.h>
#define BUF_SIZ 4096
void cut(char *s)
{
while (*s && (*s != '\r') && (*s != '\n'))
s++;
*s = '\0';
}
DWORD WINAPI reader(PVOID pParam)
{
char line[BUF_SIZ];
SOCKET s;
s = *(SOCKET*)pParam;
while(fgets(line, sizeof(line) - 3, stdin))
{
cut(line);
strcat(line, "\r\n"); /* passt sicher */
if (send(s, line, strlen(line), 0) == -1)
return 1;
}
return 0;
}
DWORD WINAPI writer(PVOID pParam)
{
char buffer[BUF_SIZ];
int bytes;
SOCKET s;
s = *(SOCKET*)pParam;
while((bytes = recv(s, buffer, sizeof(buffer), 0)) > 0)
fwrite(buffer, 1, bytes, stdout);
return 0;
}
int main(int argc, char *argv[])
{
HANDLE threads[2];
unsigned long id;
struct sockaddr_in addr;
struct hostent *host;
SOCKET s;
WSADATA wsa;
if (argc != 3)
{
fprintf(stderr, "usage: %s <Host> <Port>\n", argv[0]);
return 1;
}
if (WSAStartup(MAKEWORD(1, 1), &wsa))
{
fprintf(stderr, "WSAStartup() failed: %i\n", WSAGetLastError());
return 2;
}
if ((addr.sin_addr.s_addr = inet_addr(argv[1])) == -1)
{
host = gethostbyname(argv[1]);
if (!host)
{
fprintf(stderr, "gethostbyname() failed: %i\n", WSAGetLastError());
return 3;
}
addr.sin_addr = *(struct in_addr*)host->h_addr;
}
if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
fprintf(stderr, "socket() failed: %i\n", WSAGetLastError());
return 4;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(atol(argv[2]));
printf("connecting to %s\n", inet_ntoa(addr.sin_addr));
if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
fprintf(stderr, "connect() failed: %i", WSAGetLastError());
return 5;
}
threads[0] = CreateThread(NULL, 0, reader, &s, 0, &id);
threads[1] = CreateThread(NULL, 0, writer, &s, 0, &id);
WaitForMultipleObjects(2, threads, FALSE, INFINITE);
closesocket(s);
return 0;
}