简单并发服务器
联系Makefile的方式就是使用它,所以在这段代码中简单的使用了Makefile,现学现卖。可能有点瑕疵,但是简单使用应该没有大问题。如有问题,还请留言留言。
主文件夹下./Makefile
CC=gcc
FLAGS= -Wall -g -lrt
TOPDIR := $(PWD)
SUBDIR := server client
OBJLINK = --std=c99
HEADDIR := $(TOPDIR)/include
DEPENDS := $(wildcard $(TOPDIR)/lib/*.c)
export CC FLAGS HEARD OBJLINK HEADDIR DEPENDS
all: $(SUBDIR) OBJ
OBJ:
make -C $(TOPDIR)/lib
LIB := $(wildcard $(TOPDIR)/lib/*.o)
#CHECKDIR:
# mkdir -p $(SUBDIR) $(BUBDIR)
$(SUBDIR):RUN
make -C $@
RUN:
.PHONY:clean
clean:
rm -rf $(OBJDIR)/*.o
头文件./include/
myhead.h
#ifndef MYHEAD_H_
#define MYHEAD_H_
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<mqueue.h>
#include<sys/msg.h>
#define MSG_R 0400
#define MSG_W 0200
#define SVMSG (MSG_R | MSG_W | MSG_R >> 3 | MSG_W >> 3)
#define MAXLINE 4096
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
struct msgbuf
{
__syscall_slong_t mtype; /* type of received/sent message */
char mtext[1]; /* text of the message */
};
#define MQ_KEY1 1234L
#define MQ_KEY2 2345L
#endif
mesg.h
#ifndef MESG_H_
#define MESG_H_
#include"myhead.h"
#define MAXMESGDATA (MAXLINE-2*sizeof(long))
#define MQ_KEY1 1234L
#define MESHDRSIZE (sizeof(struct mymsg) - MAXMESGDATA)
struct mymsg
{
long len;
long type;
char data[MAXLINE];
};
ssize_t mesg_send(int, struct mymsg*);
//void Mesg_send(int, struct mymsg*);
ssize_t mesg_recv(int, struct mymsg*);
//ssize_t Mesg_recv(int, struct mymsg*);
void sig_chld(int signo);
#endif
简单依赖文件./lib/
Makefile
SOURCES := $(wildcard *.c)
TARGETS := $(patsubst %.c, %.o, $(SOURCES))
all:$(TARGETS)
$(TARGETS):%.o:%.c
$(CC) -c $< $(FLAGS) -o $@ -I$(HEADDIR)
clean:
-rm -rf *.o
recv.c
#include"mesg.h"
ssize_t mesg_recv(int fd, struct mymsg *msg)
{
ssize_t n = 0;
do
{
n = msgrcv(fd, &(msg->type), MAXMESGDATA, msg->type, 0);
}while(n == -1 && errno == EINTR);
if(n < 0)
perror("recv error");
msg->len = n;
return n;
}
send.c
#include"mesg.h"
ssize_t mesg_send(int fd, struct mymsg* msg)
{
return (msgsnd(fd, &(msg->type), msg->len, 0));
}
wait.c
#include"mesg.h"
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
return;
}
client文件 ./client/
SOURCES := $(wildcard *.c)
#TARGETS := $(patsubst %.c, %, $(SOURCES))
#all:$(TARGETS)
#$(TARGETS):%.o:%.c
client:$(SOURCES)
$(CC) $^ $(DEPENDS) $(FLAGS) -o $@ -I$(HEADDIR)
.PHONY:clean
clean:
-rm -rf *.o
client_main.c
#include"mesg.h"
void client(int, int);
int main(int argc, char **argv)
{
int readid, writeid;
writeid = msgget(MQ_KEY1, 0);
readid = msgget(IPC_PRIVATE, SVMSG | IPC_CREAT);
client(readid, writeid);
msgctl(readid, IPC_RMID, NULL);
return 0;
}
client.c
#include"mesg.h"
void client(int readfd, int writefd)
{
ssize_t len;
struct mymsg msg;
char * ptr = NULL;
snprintf(msg.data, MAXMESGDATA, "%d", readfd);
len = strlen(msg.data);
ptr = msg.data + len + 1;
msg.data[len] = ' ';
fgets(ptr, MAXMESGDATA - len - 1, stdin);
len = strlen(msg.data);
if(msg.data[len - 1])
{
len--;
}
msg.len = len;
msg.type = 1;
len = mesg_send(writefd, &msg);
sleep(1);
while((len = mesg_recv(readfd, &msg)) > 0)
{
write(STDOUT_FILENO, msg.data, len);
}
sleep(10);
return;
}
server文件./server/
Makefile
SOURCES := $(wildcard *.c)
#TARGETS := $(patsubst %.c, %.o, $(SOURCES))
#all:$(TARGETS)
#$(TARGETS):%.o:%.c
server:$(SOURCES)
$(CC) $^ $(DEPENDS) $(FLAGS) -o $@ -I$(HEADDIR)
.PHONY:clean
clean:
-rm -rf *.o
server_main.c
#include"mesg.h"
void server(int, int);
int main(int argc, char**argv)
{
int msqid;
msqid = msgget(MQ_KEY1, SVMSG | IPC_CREAT);
server(msqid, msqid);
return 0;
}
server.c
#include"mesg.h"
void server(int readfd, int writefd)
{
ssize_t len;
struct mymsg msg;
FILE* fp = NULL;
char * ptr = NULL;
msg.type = 0;
signal(SIGCHLD, sig_chld);
for(;;)
{
msg.type = 1;
len = mesg_recv(readfd, &msg);
msg.data[len] = '\0';
printf("recv %s\n", msg.data);
if(NULL == (ptr = strchr(msg.data, ' ')))
{
printf("error geshi\n");
continue;
}
ptr++;
writefd = atoi(msg.data);
if(fork() == 0)
{
if((fp = fopen(ptr, "r")) == NULL)
{
snprintf(msg.data + len, sizeof(msg.data) - len, ": can not open, %s\n", strerror(errno));
msg.len = strlen(ptr);
memmove(msg.data, ptr, msg.len);
mesg_send(writefd, &msg);
continue;
}
while(NULL!= fgets(msg.data, MAXMESGDATA, fp))
{
msg.len = strlen(msg.data);
mesg_send(writefd, &msg);
}
fclose(fp);
msg.len = 0;
mesg_send(writefd, &msg);
exit(0);
}
}
}