您的位置:首页 > 其它

在进程间,通过socket()进行通信,实现聊天功能

2013-01-08 10:59 567 查看
这里的服务器只是作为一个相当于中转站的功能,把收到的数据写到共享内存,把要读取的数据从共享内存发给需要的进程,,,,,代码,改自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地址 姓名
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: