To twój szczęśliwy dzień:
main.c
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
#include <stdio.h>
#include <string.h>
#include <assert.h>
struct server_context {
const char *port;
SOCKET listen_socket;
};
enum server_error {
server_failed_to_getaddrinfo = 1,
server_failed_to_create_socket,
server_failed_to_bind_socket,
server_failed_to_listen,
server_failed_to_accept
};
struct server_context create_server(const char *port, int *output_error_type, int *output_error) {
assert(output_error_type);
assert(output_error);
int error = 0;
struct addrinfo *info = 0;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_PASSIVE
};
struct server_context server = {
.port = port,
.listen_socket = INVALID_SOCKET
};
if(error = getaddrinfo(0, server.port, &hints, &info)) {
*output_error_type = server_failed_to_getaddrinfo;
*output_error = error;
goto panic;
}
if(INVALID_SOCKET == (server.listen_socket = socket(info->ai_family, info->ai_socktype, info->ai_protocol))) {
*output_error_type = server_failed_to_create_socket;
*output_error = WSAGetLastError();
goto panic;
}
if(SOCKET_ERROR == (bind(server.listen_socket, info->ai_addr, (int) info->ai_addrlen))) {
*output_error_type = server_failed_to_bind_socket;
*output_error = WSAGetLastError();
goto panic;
}
panic:
freeaddrinfo(info);
return server;
}
void server_listen(struct server_context *server, int *output_error_type, int *output_error) {
if(SOCKET_ERROR == listen(server->listen_socket, SOMAXCONN)) {
*output_error_type = server_failed_to_listen;
*output_error = WSAGetLastError();
}
}
SOCKET server_accept_client(struct server_context *server, int *output_error_type, int *output_error) {
SOCKET client_socket = accept(server->listen_socket, NULL, NULL);
if(client_socket == INVALID_SOCKET) {
*output_error_type = server_failed_to_accept;
*output_error = WSAGetLastError();
}
return client_socket;
}
void serve_file_to(SOCKET client_socket, const char *filename) {
FILE* fp;
char buffer[1024];
fp = fopen(filename, "r");
while(fgets(buffer, sizeof(buffer)/sizeof(buffer[0]), fp)) {
printf("#sending: %s", buffer);
send(client_socket, buffer, strlen(buffer), 0);
}
send(client_socket, "\n", strlen("\n"), 0);
fclose(fp);
}
WSADATA const * wsa_startup(int *result) {
static WSADATA wsa_data;
int wsa_startup_errorcode = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if(result) {
*result = wsa_startup_errorcode;
}
return &wsa_data;
}
int wsa_cleanup(void) {
return WSACleanup();
}
#define GUARD(error_pointer, panic_label, expr) expr; if(error_pointer) { goto panic_label; }
int main() {
wsa_startup(0);
int err_type = 0, err = 0;
puts("#create_server(...)...");
GUARD(err_type, panic, struct server_context server = create_server("1337", &err_type, &err));
puts("#server_listen(...)...");
GUARD(err_type, panic, server_listen(&server, &err_type, &err));
puts("#server_accept_client(...)...");
GUARD(err_type, panic, SOCKET client_socket = server_accept_client(&server, &err_type, &err));
//we don't need it anymore
closesocket(server.listen_socket);
serve_file_to(client_socket, "list.txt");
const char *finish_connection_message = "end\n";
send(client_socket, finish_connection_message, strlen(finish_connection_message), 0);
shutdown(client_socket, SD_SEND);
panic:
if(err_type) {
fprintf(stderr, "server error: %d | %d", err_type, err);
}
closesocket(server.listen_socket);
return wsa_cleanup();
}
main.java
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
int port = 1337;
String ip = "localhost";
Socket socket = new Socket(ip, port);
DataInputStream input = new DataInputStream(socket.getInputStream());
//readLine zostało deprecjonowane, ale trzeba poużywać póki można :]
for(String message; null != (message = input.readLine());) {
//srsly, nie ma potrzeby słania takiej wiadomości
if("end".equals(message)) {
break;
}
System.out.println(message);
}
socket.close();
}
}
list.txt
Pierwsze zdanie.
Jakies fajne dane.
Trzecie zdanie.
Po co komu kropka?
albo inne znaki
ehh
server stdout
#create_server(...)...
#server_listen(...)...
#server_accept_client(...)...
#sending: Pierwsze zdanie.
#sending: Jakies fajne dane.
#sending: Trzecie zdanie.
#sending: Po co komu kropka?
#sending: albo inne znaki
#sending: ehh
client stdout
Pierwsze zdanie.
Jakies fajne dane.
Trzecie zdanie.
Po co komu kropka?
albo inne znaki
ehh