这里的服务器只是作为一个相当于中转站的功能,把收到的数据写到共享内存,把要读取的数据从共享内存发给需要的进程,,,,,代码,改自internet
/**这是服务器的代码/
#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<errno.h>
#include<sys/shm.h>
#include<time.h>
#define PERM S_IRUSR|S_IWUSR
#define port 8080 //宏定义定义通信端口
#define BACKLOG 10 //宏定义,定义服务程序可以连接的最大客户数量
#define WELCOME "|----------Welcome to the chat room! ----------|" //宏定义,当
int main(int argc, char *argv[])
{
int sockfd,clientfd,sin_size,recvbytes; //定义监听套接字、客户套接字
pid_t pid,ppid; //定义父子线程标记变量
key_t shmid;
char buf[255], *r_addr, *w_addr, temp[255]; //定义临时存储区
struct sockaddr_in their_addr; //定义地址结构
struct sockaddr_in my_addr;
if((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1)
{
fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));
exit(1);
}
sockfd = socket(AF_INET,SOCK_STREAM,0);//创建基于流套接字
printf("socket is %d\n",sockfd);
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),8);
if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}
printf("bing success!\n");
if(listen(sockfd,BACKLOG) == -1)//在指定端口上监听
{
perror("listen");
exit(1);
}
printf("listening......\n");
while(1)
{
if((clientfd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)//接收客户端连接
{
perror("accept");
exit(1);
}
send(clientfd,WELCOME,strlen(WELCOME),0);//发送问候信息
ppid = fork();//创建子进程
if(ppid == 0)
{
pid = fork(); //创建子进程
while(1)
{
if(pid > 0)
{
//父进程用于接收信息
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);
}
else if(pid == 0)
{
//子进程用于发送信息
sleep(2);
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)
{
perror("send");
}
memset(r_addr, '\0', 1024);
strcpy(r_addr,temp);
}
}
else
perror("fork");
} //while
}
}
printf("------------------------------\n");
free(buf);
close(sockfd);
close(clientfd);
return 0;
}
/*这是客户端*/
#include<stdio.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
#include<netdb.h>
#include<unistd.h>
#include<signal.h>
#include <fcntl.h>
#include<time.h>
#define port 8080
int main(int argc, char *argv[])
{
struct sockaddr_in clientaddr;//定义地址结构
pid_t pid;
int clientfd,sendbytes,recvbytes;//定义客户端套接字
char *buf,*buf_r;
if(argc < 3)
{
printf("usage:\n");
printf("host port name\n");
exit(1);
}
if((clientfd = socket(AF_INET,SOCK_STREAM,0)) == -1) //创建客户端套接字
{
perror("socket\n");
exit(1);
}
open("chenyu.dat",O_CREAT|O_RDWR,0666);
printf("sockfd is %d\n",clientfd);
//绑定客户端套接字
clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(port);
if(inet_pton(AF_INET,argv[1],&clientaddr.sin_addr) < 0)
{
printf("inet_pton err\n");
exit(1);
}
bzero(&(clientaddr.sin_zero),8);
if(connect(clientfd,(struct sockaddr *)&clientaddr,sizeof(struct sockaddr)) == -1) //连接服务端
{
perror("connect\n");
exit(1);
}
buf=(char *)malloc(120);
memset(buf,0,120);
buf_r=(char *)malloc(100);
if( recv(clientfd,buf,100,0) == -1)
{
perror("recv:");
exit(1);
}
printf("\n%s\n",buf);
pid = fork();//创建子进程
while(1)
{
if(pid > 0){
//父进程用于发送信息
strcpy(buf,argv[2]);
strcat(buf,":");
memset(buf_r,0,100);
fgets(buf_r,100,stdin);
strncat(buf,buf_r,strlen(buf_r)-1);
if((sendbytes = send(clientfd,buf,strlen(buf),0)) == -1)
{
perror("send\n");
exit(1);
}
}
else if(pid == 0)
{
//子进程用于接收信息
memset(buf,0,100);
if(recv(clientfd,buf,100,0) <= 0)
{
perror("recv:");
close(clientfd);
raise(SIGSTOP);
exit(1);
}
printf("%s\n",buf);
}
else
perror("fork");
}
close(clientfd);
return 0;
}
在客户端运行时,格式: ./client ip地址 姓名