И это всё МОЁ
Здравствуйте! Помогите, пожалуйста со следующей проблемой. У меня есть готовый код, описывающий взаимодействие клиент-сервер. Но он работает как общий чат.То есть при отправке сообщения на сервер это сообщение видят все клиенты. Этот код нужно доработать, так чтобы клиент мог выбирать адресата из списка всех клиентов и общаться только с ним. Можете подсказать как это организовать? Или какие ошибки исправить в коде?
Код сервера:
include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <poll.h>
#define IPADDRESS "127.0.0.1"
#define PORT 6666
#define MAXLINE 1024
#define LISTENQ 5
#define OPEN_MAX 1000
#define INFTIM -1
int bind_and_listen()
{
int serverfd;
struct sockaddr_in my_addr;
unsigned int sin_size;
if((serverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf ("error socket"
;
return -1;
}
printf("socket ok\n"
;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 0);
if(bind(serverfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
{
printf("error bind"
;
return -2;
}
printf("bind ok\n"
;
if(listen(serverfd, LISTENQ) == -1)
{
printf("error listen"
;
return -3;
}
printf("listen ok\n"
;
return serverfd;
}
void do_poll(int listenfd)
{
int connfd, sockfd;
struct sockaddr_in cliaddr;
socklen_t cliaddrlen;
struct pollfd clientfds[OPEN_MAX];
int maxi;
int sin_port2[5];
int i,j;
int nready;
clientfds[0].fd = listenfd;
clientfds[0].events = POLLIN;
for(i = 1; i<OPEN_MAX; i++)
clientfds[i].fd = -1;
maxi = 0;
while(1)
{
nready = poll(clientfds, maxi+1, INFTIM);
if(nready == -1)
{
printf("poll error"
;
exit(1);
}
if(clientfds[0].revents & POLLIN)
{
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen)) <0)
{
printf("accept error"
;
exit(1);
}
fprintf(stdout, "accept a new client:%s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
for(i = 1; i<OPEN_MAX; i++)
{
if(clientfds[i].fd<0)
{
clientfds[i].fd = connfd;
break;
}
}
if(i == OPEN_MAX)
{
fprintf(stderr, "too many clients.\n"
;
exit(1);
}
sin_port2[i]=cliaddr.sin_port;
clientfds[i].events = POLLIN;
maxi = (i>maxi?i:maxi);
if(--nready<=0)
continue;
}
char buf[MAXLINE];
char BUF[80];
memset(buf, 0, MAXLINE);
int readlen = 0;
for(i = 1; i<maxi; i++)
{
if(clientfds[i].fd<0) continue;
if(clientfds[i].revents & POLLIN)
{
readlen = read(clientfds[i].fd, buf, MAXLINE);
if(readlen == 0)
{
close(clientfds[i].fd);
clientfds[i].fd = -1;
continue;
}
printf("msg is:"
;
memset(BUF,0,sizeof(BUF));
sprintf(BUF,"%d :%s",sin_port2[i],buf);
printf("%s",BUF);
for(j=1;j<maxi;j++)
{
if(i!=j){
write(clientfds[j].fd, BUF, sizeof(BUF));
}
}
}
}
}
}
int main(int argc, char* argv[])
{
int listenfd = bind_and_listen();
if(listenfd<0)
{
return 0;
}
do_poll(listenfd);
return 0;
}
Код клиента:
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<poll.h>
#define IPADDRESS "127.0.0.1"
#define PORT 20113
#define MAXLINE 1024
#define max(a, b) (a>b)?a:b
static void handle_connection(int sockfd);
int main(int argc, char* argv[])
{
int connfd = 0;
int clen = 0;
struct sockaddr_in client;
if(argc<2)
{
printf("Usage: clientent[server IP address]\n"
;
return -1;
}
client.sin_family = AF_INET;
client.sin_port = htons(PORT);
client.sin_addr.s_addr = inet_addr(argv[1]);
connfd = socket(AF_INET, SOCK_STREAM, 0);
if(connfd<0)
{
printf("error socket"
;
return -1;
}
if(connect(connfd, (struct sockaddr*)&client, sizeof(client))<0)
{
printf("error connect"
;
return -1;
}
handle_connection(connfd);
return 0;
}
static void handle_connection(int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
int maxfdp, stdineof;
struct pollfd pfds[2];
int n;
pfds[0].fd = sockfd;
pfds[0].events = POLLIN;
pfds[1].fd = STDIN_FILENO;
pfds[1].events = POLLIN;
while(1)
{
poll(pfds, 2, -1);
if(pfds[0].revents & POLLIN)
{
n = read(sockfd, recvline, MAXLINE);
if(n == 0)
{
fprintf(stderr, "client: server is closed.\n"
;
close(sockfd);
}
write(STDOUT_FILENO, recvline, n);
}
if(pfds[1].revents & POLLIN)
{
n = read(STDIN_FILENO, sendline, MAXLINE);
if(n == 0)
{
shutdown(sockfd, SHUT_WR);
continue;
}
write(sockfd, sendline, n);
}
}
}
[code = C]