Сервер подключен к нескольким клиенту. Клиент отправляет сообщение на сервер. Если сервер закрывает свой сокет, он потеряет соединение с другими клиентами. Мне нужно сообщить серверу, что клиент выключен, и как закрыть его для конкретного клиента в следующем простом примере:
Сервер:
#include "wrappers.h"
int main(){
unsigned int Sockfd, NewSockfd, ClntLen;
sockaddr_in ClntAddr, ServAddr;
int Port = SERV_TCP_PORT;
char String[MAX_SIZE];
int Len;
// open a TCP socket (an Internet stream socket)
Sockfd = Socket(AF_INET, SOCK_STREAM, 0); // socket() wrapper fn
// bind the local address, so that the client can send to server
memset((char*)&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
ServAddr.sin_port = htons(Port);
Bind(Sockfd, (sockaddr*) &ServAddr, sizeof(ServAddr));
// listen to the socket
Listen(Sockfd, 5);
for(;;){
// wait for a connection from a client; this is an iterative server
ClntLen = sizeof(ClntAddr);
NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);
if(NewSockfd < 0){
perror("Can't bind local address!");
}
// read a message from the client
Len = read(NewSockfd, String, MAX_SIZE);
String[Len] = 0;// make sure it a proper string
printf("%s\n", String);
write(NewSockfd, "hello", sizeof("hello"));
cout<<"wrote to client"<<endl;
close(NewSockfd);
}
}
Клиент:
#include "wrappers.h"
int main()
{
int Sockfd;
sockaddr_in ServAddr;
char ServHost[] = "localhost";
hostent *HostPtr;
int Port = SERV_TCP_PORT;
int BuffSize = 0;
// get the address of the host
HostPtr = Gethostbyname(ServHost);
if(HostPtr->h_addrtype != AF_INET){
perror("Unknown address type!");
exit(1);
}
memset((char *) &ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = ((in_addr*)HostPtr->h_addr_list[0])->s_addr;
ServAddr.sin_port = htons(Port);
bool loop = true;
int i= 0;
while(loop){
// open a TCP socket
Sockfd = Socket(AF_INET, SOCK_STREAM, 0);
// connect to the server
Connect(Sockfd, (sockaddr*)&ServAddr, sizeof(ServAddr));
if(i>5){
loop = false;
}
i++;
// write a message to the server
write(Sockfd, "hello world", sizeof("hello world"));
char String[10];
int Len = read(Sockfd, String, MAX_SIZE);
String[Len] = 0;// make sure it a proper string
printf("%s === \n", String);
}
close(Sockfd);
}
Если client
сокет закрыт, вы получите возвращаемое значение 0 на стороне сервера от read
. Это указывает на конец клиентского соединения.
Если вы попытаетесь write
в такой сокет, вы получите сигнал SIGPIPE
, и write
вернет ошибку с установкой errno
в EPIPE
("Broken Pipe").