Я пытался реализовать взаимодействие клиента с клиентом с сервером между ними. Функция сервера заключается в том, что, когда клиент полагает, что клиент A отправляет сообщение серверу, сервер должен отправить это сообщение другому клиенту, клиенту B. То же самое, когда клиент B отправляет сообщение на сервер, он должен быть переадресован к клиенту А. Эти программы включают только двух клиентов. Я получаю ошибки, когда я выполняю код является то, что он говорит:Связь клиента с клиентом с помощью функции select() в c
Socket Operation on Non-socket
Я получаю эту ошибку, когда получил сообщение от клиента A пересылается клиент B. Я думаю, что проблема связана с хранением полученного адрес клиента B по адресу клиента А. Я не уверен в этом.
Код моего сервера до сих пор.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#define SERVER_PORT 5009
int main(){
unsigned int sockfd, c,c1,c2, clientlen, clientfd;
struct sockaddr_in server;
struct sockaddr_in client1;
int clientsocks[2];
char rmsg1[100], msg1[100],rmsg2[100], msg2[100];
char w_msg[] = "Connection to server established";
fd_set readfds; // For temp file descriptor list.
clientsocks[0] = 0 ;
clientsocks[1] = 0 ;
//Socket Creation Process.
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("Socket cannot be created");
}
//For reusing the socket.
int on = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
//Socket address
bzero((char *) &server, sizeof(server));
server.sin_family = AF_INET; // IPv4 internet Protocols
inet_aton("127.0.0.1", &server.sin_addr);
server.sin_port = htons(SERVER_PORT);
//Binding socket to address.
if (bind(sockfd, (struct sockaddr*)&server, sizeof (server)) < 0){
perror("Bind Error");
exit(EXIT_FAILURE);
}
//Listen to accept connection.
if(listen(sockfd, SOMAXCONN) < 0){
perror("Error in Listen");
exit(EXIT_FAILURE);
}
unsigned int new_sock;
clientlen =sizeof(client1);
int activity;
while(1){
//Clear socket set.
FD_ZERO(&readfds);
//Adding main sockfd to the socket set.
FD_SET(sockfd, &readfds);
unsigned int max_sd = sockfd;
//Add child sockets to set.
for(int i=0 ; i<2; i++){
c = clientsocks[i];
if(c > 0)
FD_SET(c, &readfds);
if(c > max_sd)
max_sd = c;
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if(activity < 0){
perror("Error in select()");
exit(EXIT_FAILURE);
}
//Incoming connection when something happens on sockfd.
if(FD_ISSET(sockfd, &readfds)){
new_sock = accept(sockfd, (struct sockaddr *) &client1, &clientlen);
if(new_sock > 0){
for(int i=0; i<2; i++){
if(clientsocks[i] == 0){
clientsocks[i] = new_sock;
break;
}
}
}
if( new_sock < 0){
perror("Error Accepting");
exit(EXIT_FAILURE);
}
if(send(new_sock, w_msg, strlen(w_msg), 0) != strlen(w_msg)){
perror("Welcome message");
exit(EXIT_FAILURE);
}
c1 = clientsocks[0];
c2 = clientsocks[1];
FD_SET(c1, &readfds);
FD_SET(c2, &readfds);
}
//Else if its not a new incoming connection.
if(FD_ISSET(c1, &readfds)){
if(recv(c1, rmsg1, 100, 0) < 0){
perror("Receive 1");
exit(EXIT_FAILURE);
}
printf("Client1 >> %s\n", rmsg1);
//Forwarding to Client B.
if(send(c2, rmsg1, 100, 0) < 0){
perror("Error forwarding to 2");
exit(EXIT_FAILURE);
}
}
if(FD_ISSET(c2, &readfds)){
if(recv(c2, rmsg2, 100, 0) < 0){
perror("Receive 2");
exit(EXIT_FAILURE);
}
printf("Client2 >> %s\n", rmsg2);
if(send(c1, rmsg2, 100, 0) < 0){
perror("Error Forwarding to 1");
exit(EXIT_FAILURE);
}
}
}
close(sockfd);
return 1;
}
Моя проблема состоит из двух клиентов только. Я был бы очень признателен, если бы вы могли указать на некоторые другие улучшения.
Если вы получили сообщение об ошибке, не допустимо, чтобы выполнение выполнялось так, как будто этого не произошло. Каждый из этих вызовов 'perror()' должен сопровождаться очисткой и возвратом. – EJP
Как клиентские сокеты хранятся в 'clientsocks'? – immibis
@EJP Вы имеете в виду, что я должен разорвать петлю и вернуться? –