Linux
#include <sys/types.h> #include <sys/socket.h> // 包含套接字函数库 #include <stdio.h> #include <netinet/in.h> // 包含AF_INET相关结构 #include <arpa/inet.h> // 包含AF_INET相关操作的函数 #include <unistd.h> #include<string.h> #include<stdlib.h> #include<fcntl.h> #include<sys/shm.h> #define PORT 8889 #define MYKEY 12345 #define SIZE 10240 int main() { int shmid; char *shmaddr; //定义子进程共用的共享内存 shmid = shmget(MYKEY, SIZE, IPC_CREAT | 0600); shmaddr= (char *) shmat(shmid, 0, 0); if(shmid==-1) { printf("shmid error\n"); } memset(shmaddr,0,SIZE); int i=0; char buf[100]; memset(buf,0,100); int server_sockfd,client_sockfd; int server_len,client_len; struct sockaddr_in server_sockaddr,client_sockaddr; server_sockfd = socket(AF_INET,SOCK_STREAM, 0); // 定义套接字类型 server_sockaddr.sin_family=AF_INET; server_sockaddr.sin_port=htons(PORT); server_sockaddr.sin_addr.s_addr=INADDR_ANY; server_len=sizeof(server_sockaddr); //允许重复使用本地地址和套接字绑定 int j=1; setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,&j,sizeof(j)); //绑定端口 if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,server_len)==-1) { perror("bind:"); exit(1); } if(listen(server_sockfd,5)==-1) { perror("listen:"); exit(1); } printf("Listening...\n"); client_len=sizeof(client_sockaddr); pid_t ppid,pid; while(1) { if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_sockaddr,&client_len))==-1) { perror("accept error:"); exit(1); } printf("%s登录服务器\n",inet_ntoa(client_sockaddr.sin_addr)); ppid=fork(); if(ppid==-1) { printf("fork 1 failed:"); } if(ppid==0) //子进程用于接收客户端信息并发送 { pid=fork(); if(pid==-1) { printf("fork 2 failed:"); exit(1); } int recvbytes; if(pid==0) //子子进程用于接收消息 { while(1) { if((recvbytes=recv(client_sockfd,buf,100,0))==-1) { perror("read client_sockfd failed:"); } // printf("recvbytes=%d\n",recvbytes); usleep(10000); printf("client send buf=%s\n",buf); for(i=0;i<1000;i++) { if(*(shmaddr+100*i)==0) { strcpy(shmaddr+100*i,buf); break; } } } } if(pid>0) //子进程用于发送消息 { while(1) { if(*(shmaddr+i*100)!=0) { // strcpy(&buf,shmaddr+100*i); // buf++; write(client_sockfd,shmaddr,SIZE); // send(client_sockfd,buf,strlen(buf),0); // printf("the server is send buf=%c",buf); // printf("send client :%s\n",(shmaddr+i*100)) ; i++; } } } } if(ppid>0) //总父进程返回等待接收消息 { close(client_sockfd); } } }
#include <sys/types.h> #include <sys/socket.h> // 包含套接字函数库 #include <stdio.h> #include <netinet/in.h> // 包含AF_INET相关结构 #include <arpa/inet.h> // 包含AF_INET相关操作的函数 #include <unistd.h> #include <string.h> #include <time.h> #define PORT 8889 #define IP_ADDR "127.0.0.1" #define SIZE 10240 int main() { struct tm *timeptr; time_t timeval; char tm[50]; //(void)time(&timeval); //printf("the date is %s\n",ctime(&timeval)); // printf("The time is %s\n",tm); int sockfd; // 用于保存客户套接字标识符 int len; // 用于客户消息长度 struct sockaddr_in address; // 定义客户套接字地址 int result; sockfd = socket(AF_INET,SOCK_STREAM, 0); // 定义套接字类型 address.sin_family = AF_INET; // 定义套接字地址中的域 address.sin_addr.s_addr = inet_addr(IP_ADDR); // 定义套接字地址 address.sin_port = htons(PORT); // 定义套接字端口 char buf[100]; // 定义要传送的消息 memset(buf,0,100); char str[120]; //存贮输入的语句 char shmaddr[SIZE]; //接受服务器发送的全部聊天数据 int i=0; char myname[100]; char say[10]={"[-_-]"}; char blank[10] = {" "}; printf("欢迎来到聊天室,请输入你的姓名:\n"); scanf("%s",myname); len = sizeof(address); result = connect(sockfd, (struct sockaddr *) &address, len); // 请求连接 if (result == -1) { perror("Connect failed"); return 1; } printf("%s成功登录服务器:\n",myname); pid_t pid; pid=fork(); if(pid==-1) { printf("fork failed"); } int sendbytes=0; if(pid==0) //子进程用于发送数据 { while(1) { scanf("%s",str); (void)time(&timeval); strcpy(tm,ctime(&timeval)); strcpy(buf,myname); //姓名传入buf中 strcat(buf,blank); strcat(buf,tm); //时间传入buf中 strcat(buf,say); strcat(buf,str); //语句传入bufz中 if((sendbytes=write(sockfd, buf, 100))==-1) { perror("send to server failed:"); } // 向服务器传送消息 usleep(1000); memset(buf,0,100); memset(tm,0,50); } } if(pid>0) //父进程用于接受消息并读取 { while(1) { read(sockfd,shmaddr,SIZE); // printf("server send shmaddr=%s\n",shmaddr); if(*(shmaddr+i*100)!=0) { printf("%s\n",(shmaddr+i*100)) ; i++; printf("\n"); } usleep(1000); } } close(sockfd); return 0; }