El código mostrado a continuación esta hecho para windows, no es el codigo mas optimo posible y en mi caso abusó mucho de los apuntadores sin embargo es posible adaptarlo para realizar cualquier operación
#include<winsock2.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32")
#define BACKLOG 256
struct sockaddr_in *server_sa;
char *readLine(SOCKET descriptor,int *len);
void writeLine(SOCKET descriptor,char *str);
DWORD WINAPI procesar_peticion(LPVOID descriptor);
int main() {
SOCKET s,c;
SOCKET *toThread;
WSADATA wsaData;
DWORD dwThreadId;
HANDLE hThread;
int b = 0,iResult;
char caracter;
memset(&wsaData,0,sizeof(WSADATA));
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return 2;
}
server_sa = calloc(1,sizeof(struct sockaddr_in));
server_sa->sin_family = AF_INET;
server_sa->sin_port = htons(10000);
server_sa->sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s,(struct sockaddr *) server_sa, sizeof(struct sockaddr)) < 0) {
perror("bind");
exit(3);
}
b = sizeof(struct sockaddr);
if(listen(s, BACKLOG) ==SOCKET_ERROR) {
fprintf(stderr,"listen %s",WSAGetLastError());
exit(4);
}
while(1) {
if((c = accept(s,(struct sockaddr *)server_sa, &b)) < 0) {
printf("WS error code: %i\n",WSAGetLastError());
perror("accept");
exit(5);
}
toThread = malloc(sizeof(SOCKET));
memcpy(toThread,&c,sizeof(SOCKET));
hThread = CreateThread(NULL,0,procesar_peticion,toThread,0,&dwThreadId);
}
}
DWORD WINAPI procesar_peticion(LPVOID descriptor) {
HANDLE thread_id;
SOCKET client;
int read_len;
int i = 0,j =0;
int entrar = 1;
char *linea;
thread_id = GetCurrentThread();
memcpy(&client,descriptor,sizeof(SOCKET));
free(descriptor);
do {
linea = readLine(client,&read_len);
if(read_len == -1) {
entrar = 0;
}
else {
printf("Linea leida: %s\nBytes leidos %i\n",linea,read_len);
writeLine(client,linea);
}
/*
i++;
if(i == 5) {
entrar = 0;
}
*/
/*
if(strncmp("exit",linea,4) == 0) {
entrar = 0;
}
*/
/*
if(read_len == 10) {
entrar = 0;
}
*/
free(linea);
}while(entrar == 1);
closesocket(client);
CloseHandle(thread_id);
}
char *readLine(SOCKET descriptor,int *len) {
char *buffer = NULL;
int i = 0,entrar = 1,len_read,max;
buffer = malloc(64);
max = 64;
do {
if(i == max) {
max *= 2;
buffer = realloc(buffer,max);
if( buffer == NULL ) {
fprintf(stderr,"realloc(): buffer len %i\n",i);
exit(0);
}
}
len_read = recv(descriptor,buffer + i,1,0);
if(len_read == 1) {
switch(buffer[i]) {
case 0xD:
case 0xA:
buffer[i] = '\0';
entrar = 0;
break;
default:
i++;
break;
}
}
else {
buffer[i] = '\0';
entrar = 0;
if(i == 0) {
i = -1;
}
}
}while(entrar && i < 1000);
if( len != NULL ) {
*len = i;
}
return buffer;
}
void writeLine(SOCKET descriptor,char *str) {
int len;
len = strlen(str);
//send(descriptor,"Usted escribio: ",16,0);
send(descriptor,str,len,0);
//send(descriptor,"\n",1,0);
}
<p>Compilamos el siguiente el código con el siguiente comando</p>
<custom_code>gcc -o servidor_eco.exe servidor_eco.c -lws2_32
Ejecutamos el servidor
servidor_eco.exe
Nos conectamos al servidor utilizando el cliente netcat:
ncat localhost 10000
Y comenzamos a mandar datos desde el cliente, terminaremos aproximadamente con la salida mostrada a continuación:
Saludos!