C言語で作成するチャットについて
LinuxでC言語のチャットプログラムを作成しています。プログラムを作ってみましたがうまく動きません。悪い個所が分からないのでお力を貸して頂きたいです課題の提出が迫っているので、よろしくお願いいたします。
<server>
#include省略
#define PORT 5320
char *show_ip(char *ip_address);
int main(void){
int soc, acc, size, child[3],width,i,count,pos,ret;
char buffer[80];
struct sockaddr_in client, server;
struct sockaddr_storage from;
struct hostent *server_host;
socklen_t len;
fd_set mask;
char host_name[257];
int temp;
memset(host_name, 0, sizeof(host_name));
gethostname(host_name, 256);
server_host = gethostbyname(host_name);
printf("\n-------- informations of server ----------\n");
printf("Host name:%s\n", host_name);
printf("IP = %s\n", show_ip(server_host->h_addr));
printf("\n\n");
soc = socket(AF_INET, SOCK_STREAM, 0);
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
bind(soc, (struct sockaddr *)&server, sizeof(server));
size = sizeof(client);
listen(soc, 5);
for (i = 0; i < 3; i++){
child[i] = -1;
}
for (;;) {
FD_ZERO(&mask);
FD_SET(soc, &mask);
for (i = 0; i < 3; i++) {
if (child[i] != -1){
FD_SET(child[i], &mask);
if(child[i]+1 > width){
width = child[i]+1;
}
}
}
switch(select(soc+1, (fd_set *) &mask, NULL, NULL, NULL))
{
case -1:
perror("select");
break;
case 0:
break;
default:
if (FD_ISSET(soc, &mask)){
len = (socklen_t) sizeof(from);
if((acc = accept(child[i], (struct sockaddr *)&from, &len)) == -1){
if(errno != EINTR){
perror("accept");
}
}else{
if(child[0]&&child[1]&&child[2]!=-1){
fprintf(stderr,"child is full : cannot accept\n");
close(acc);
}else{
if(child[0] == -1){
child[0] = acc;
}else if(child[1] == -1){
child[1] = acc;
}else{
child[2] = acc;
}
}
}
}
for(i=0;i<3;i++){
if(child[i]!=-1){
if(FD_ISSET(child[i],&mask)){
memset(buffer, '\0', sizeof(buffer));
recv(child[i], buffer, 80, 0);
printf("%s> ", show_ip((char *)&client.sin_addr));
printf("%s", buffer);
if(strncmp(buffer, "exit", 4) == 0) break;
for(i=0;i<3;i++)
{
send(child[i],show_ip((char *)&client.sin_addr),80,0);
send(child[i],buffer,80,0);
close(child[i]);
}
(void) close(child[i]);
child[i] = -1;
}
}
break;
}
}
}
}
char *show_ip(char *ip_address){
static char ip[7];
char ipnum[4];
bcopy(ip_address, ipnum, 4);
sprintf(ip, "%u.%u.%u.%u",(unsigned char)ipnum[0], (unsigned char)ipnum[1], (unsigned char)ipnum[2],(unsigned char)ipnum[3]);
return ip;
}
<client>
#include省略
#define STDIN_FD 0
#define PORT 5320
int select_func(int sockfd);
void err_func(char *msg){
perror(msg);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv){
int sockfd, len;
char buf[BUFSIZ];
struct sockaddr_in serv;
unsigned short port;
if(argc != 3){
printf("usage: progname serv_ip serv_port\n");
exit(EXIT_FAILURE);
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_func("socket");
serv.sin_family = PF_INET;
port = (unsigned short)atoi(argv[2]);
serv.sin_port = htons(port);
inet_aton(argv[1], &(serv.sin_addr));
if(connect(sockfd, (struct sockaddr *)&serv, sizeof(struct sockaddr_in)) < 0)
err_func("connect");
do{
if(select_func(sockfd) == 0){
len = recv(sockfd, buf, BUFSIZ, 0);
buf[len] = '\0';
printf("-> %s\n", buf);
}else{
len = read(STDIN_FD, buf, BUFSIZ);
len = send(sockfd, buf, len, 0);
}
}while(strncmp(buf, "EXIT\r\n", 6) != 0 && strncmp(buf, "EXIT\n", 5) != 0);
close(sockfd);
return 0;
}
int select_func(int sockfd){
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
FD_SET(STDIN_FD, &rfds);
if(select(sockfd+1, &rfds, NULL, NULL, NULL) < 0)
err_func("select");
if(FD_ISSET(STDIN_FD, &rfds))
return STDIN_FD;
return sockfd;
}
お礼
おおっホントだ、できました! 各関数にローカル変数を指定するのとグローバル変数とは別なんですね。 大変参考になりました、どうもありがとうございました!