Я извиняюсь за плохой английский и дать код для Windows, я не мог писать в Linux сейчас сильных причин, но я надеюсь сделать это в следующий раз.
Хотя версия для Windows может быть немного пугающей вначале, будет ясно, если вы внимательно прочитаете код. Кроме того, вы должны внести некоторые изменения из Windows в версию POSIX Linux, что очень прямо (на примерах, используя потоки POSIX, а не потоки Windows).
Я создал для сокетов, чтобы получать соединения и изменять сообщения в шаблоне recv-send, как вы ожидали. Каждый сервер может получать количество соединений, ограниченных MAX_THREADS (каждый поток управляет одним соединением). Обратите внимание, что select() возвращает сокет сервера, у которого есть ожидающее соединение с вызовом accept().
#include <winSock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <WS2tcpip.h>
#include <stdint.h>
#include <processthreadsapi.h>
#include <heapapi.h>
#define MAX_THREADS 20
#define MAX_BUFF_SIZE 256
struct thread_list
{
HANDLE thread;
struct thread_list *next;
};
struct MyData {
char name_server[8];
int sock;
};
void log_error(char *msg)
{
printf(msg);
exit(EXIT_FAILURE);
}
void initSocket(int *server, struct sockaddr_in *addr, char *ip, uint16_t porta){
if ((*server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
log_error("Erro socket\n");
}
addr->sin_port = htons(porta);
addr->sin_addr.s_addr = inet_addr(ip);
addr->sin_family = AF_INET;
if((bind(*server, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0))
log_error("ERROR bind()");
if(listen(*server, SOMAXCONN) == SOCKET_ERROR)
log_error("error listen()");
return;
}
DWORD WINAPI ThreadFunc(void *data)
{
char messageFrom[MAX_BUFF_SIZE], messageTo[MAX_BUFF_SIZE];
struct MyData *ptr = (struct MyData *)data;
// pattern: recv - send
while(1)
{
recv(ptr->sock, messageFrom, MAX_BUFF_SIZE, 0);
printf(messageFrom);
strcpy(messageTo, "Message received. Complete send() message in your way");
send(ptr->sock, messageTo, strlen(messageTo), 0);
}
// Save the whales, feed the hungry, free the mallocs()'s
}
int main(int argc, char **argv) {
struct sockaddr_in addr1, addr2;
int server1, server2;
struct MyData *pDataArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
// init num current active threads
int num_threads = 0;
if(argc < 5)
log_error("Format: ./prog ip1 port1 ip2 port2\n");
initSocket(&server1, &addr1, argv[1], (uint16_t)atoi(argv[2]));
initSocket(&server2, &addr2, argv[3], (uint16_t)atoi(argv[4]));
int evtsock, novosock;
fd_set readfds;
FD_SET(server1, &readfds);
FD_SET(server2, &readfds);
struct sockaddr their_addr;
socklen_t strg_sz = sizeof(their_addr);
while(1) { //escuta conexoes
evtsock = select(0, &readfds, NULL, NULL, NULL);
pDataArray[num_threads]->sock = accept(evtsock, &their_addr, &strg_sz);
if(pDataArray[num_threads]->sock == INVALID_SOCKET)
log_error("ERROR accept()");
if(num_threads == MAX_THREADS){
// now this program will run forever. It is recommended to manage signals like SIGTERM
// free mallocated memory and release all resources carefully
printf("Max connections reached\n");
continue;
}
pDataArray[num_threads] = (struct MyData *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(struct MyData));
if(evtsock == server1)
strcpy(pDataArray[num_threads]->name_server, "server1");
else if(evtsock == server1)
strcpy(pDataArray[num_threads]->name_server, "server2");
else
printf("Unmanaged event\n");
hThreadArray[num_threads] = CreateThread(NULL, 0, ThreadFunc, &pDataArray[num_threads], 0, NULL);
num_threads++;
}
return 0;
}
Возможно, вы можете использовать 'fork' ??? –