//--------------------------------server.c--------------------------------------------------
//包含工程所需的头文件
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h> //数据类型定义
#include<sys/stat.h>
#include<netinet/in.h> //定义数据结构sockaddr_in
#include<sys/socket.h> //提供socket函数及数据结构
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<errno.h>
#include <arpa/inet.h>
#define MYPORT 3490 //宏定义定义通信端口
#define BACKLOG 10 //宏定义,定义服务程序可以连接的最大客户数量
#define WELCOME "|----------Welcome to the chat room! ----------|" //宏定义,当客户端连接服务端时,想客户发送此欢迎字符串
//创建共享存储区
key_t shm_create(void)
{
key_t shmid;
if((shmid = shmget(IPC_PRIVATE,1024,S_IRUSR|S_IWUSR)) == -1)
{
fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));
exit(1);
}
return shmid;
}
//端口绑定函数,创建套接字,并绑定到指定端口
int bindPort(unsigned short int port)
{
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);//创建基于流套接字
my_addr.sin_family = AF_INET;//IPv4协议族
my_addr.sin_port = htons(port);//端口转换
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),0);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1)
{
printf("bind error\n");
exit(1);
}
printf("bind success!\n");
return sockfd;
}
int main(int argc, char *argv[])
{
int sockfd,clientfd,sin_size,recvbytes; //定义监听套接字、客户套接字
pid_t pid,ppid; //定义父子线程标记变量
char *buf, *r_addr, *w_addr, *temp;//="\0"; //定义临时存储区
struct sockaddr_in their_addr; //定义地址结构
key_t shmid;
memset(&their_addr,0,sizeof(struct sockaddr_in));
shmid = shm_create(); //创建共享存储区
temp = (char *)malloc(255);
sockfd = bindPort(MYPORT);//绑定端口
while(1)
{
if(listen(sockfd,BACKLOG) == -1)//在指定端口上监听
{
printf("listen error\n");
exit(1);
}
printf("listening......\n");
clientfd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size) ;
if(clientfd == -1)//接收客户端连接
{
printf("accept error\n");
exit(1);
}
printf("accept from:%s\n",inet_ntoa(their_addr.sin_addr));
send(clientfd,WELCOME,strlen(WELCOME),0);//发送问候信息
buf = (char *)malloc(255);
ppid = fork();//创建子进程
if(ppid == 0)//为子进程
{
pid = fork(); //创建子进程
//while(1)
//{
if(pid > 0)
{
while(1){//父进程用于接收信息
memset(buf,0,255);
if((recvbytes = recv(clientfd,buf,255,0)) <= 0)
{
perror("recv1");
close(clientfd);
raise(SIGKILL);
exit(1);
}
w_addr = shmat(shmid, 0, 0);
memset(w_addr, '\0', 1024);
strncpy(w_addr, buf, 1024);
printf(" %s\n",buf);
}
}
else if(pid == 0)
{
while(1){//子进程用于发送信息
sleep(1);
r_addr = shmat(shmid, 0, 0);
if(strcmp(temp,r_addr) != 0)
{
strcpy(temp,r_addr);
if(send(clientfd,r_addr,strlen(r_addr),0) == -1)
{
printf("send error\n");
}
memset(r_addr, '\0', 1024);
strcpy(r_addr,temp);
}
}
}
else perror("fork");
//}
}
}
printf("------------------------------\n");
free(buf);
close(sockfd);
close(clientfd);
return 0;
}
linux-chatroom.rar_linux 多路复用
版权申诉
53 浏览量
2022-09-21
08:30:57
上传
评论
收藏 3KB RAR 举报
寒泊
- 粉丝: 75
- 资源: 1万+