//通过"@用户名"实现单发,"->all"实现群发
//1net.h
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<pthread.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/wait.h>
#include <arpa/inet.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<assert.h>
#include<time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include<sys/un.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
//127.0.0.1
#define SERVPORT 44432
#define BACKLOG 10
#define MAXDATASIZE 256
#define STDIN 0
#define COUNT 5
//2Server_multiple.c
#include "net.h"
int socket_fd[COUNT];
void pthread_function(int client_fd)
{
char message[1500];
char buf[1024];
int i,recvbytes;
char name[20];
recvbytes=recv(client_fd,name,20,0);
name[recvbytes]=':';
name[recvbytes]='\0';
while(1)
{
if((recvbytes=recv(client_fd,buf,1024,0))==-1)
{
perror("recv error\n");
exit(1);
}
if(recvbytes==0)
{
printf("%s bye!(%sLeave the chat room)\n",name,name);
break;
}
buf[recvbytes]='\0';
for(i=0;i<COUNT;i++)
{
if(socket_fd[i]==-1)
{
continue;
}
else
{
message[0]='\0';
strcat(message,name);
strcat(message,buf);
if(send(socket_fd[i],message,strlen(message),0)==-1)
{
perror("send error\n");
exit(1);
}
}
}
}
close(client_fd);
for(i=0;i<COUNT;i++)
{
if(socket_fd[i]==client_fd)
{
socket_fd[i]=-1;
}
}
pthread_exit(NULL);
}
int main(int argc, char* argv[])
{
int i;
for(i=0;i<COUNT;i++)
{
socket_fd[i]=-1;
}
pthread_t id;
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(atoi(argv[2]));
my_addr.sin_addr.s_addr=inet_addr(argv[1]);
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind false!\n");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen false!\n");
exit(1);
}
i=0;
while(1)
{
sin_size=sizeof(struct sockaddr_in);
if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)
{
perror("accept error!\n");
exit(1);
}
while(socket_fd[i]!=-1)
{
i=(i+1)%COUNT;
}
socket_fd[i]=client_fd;
pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)client_fd);//(int *)client_fd,修改成(int *)(long)client_fd(形参int* 是 8 字节,而实参 int client_fd却是 4 字节。为了避免这个警告变为long int 型)
}
}
//3Client_multiple.c
#include "net.h"
char recv_buf[1500],send_buf[1024];
char name[20];
void pthread_function(int sockfd)
{
int recvbytes;
while(1)
{
if((recvbytes=recv(sockfd,recv_buf,1500,0))==-1)
{
perror("recv error\n");
exit(1);
}
else
{
recv_buf[recvbytes]='\0';
char *x,*y;
x=strstr(recv_buf,"@");
y=strstr(recv_buf,"->all");
int flag=1;
if(x!=NULL)
{
x=strcat(x,":");
flag=strcmp(x+1,name);
if(!flag)
{
recv_buf[recvbytes]='\0';
printf("%s\n",recv_buf);
}
}
else if(y!=NULL)
{
flag=strcmp(y,"->all");
recv_buf[recvbytes-5]='\0';
printf("%s\n",recv_buf);
}
else;
}
}
}
int main(int argc, char* argv[])
{
pthread_t id;
int sockfd;
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(atoi(argv[2]));
server_addr.sin_addr.s_addr=inet_addr(argv[1]);//127.0.0.1
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket error\n");
exit(1);
}
if(connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
{
perror("connect error\n");
exit(1);
}
printf("input your name:");
scanf("%s",name);
strcat(name,":");
send(sockfd,name,strlen(name),0);
pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)sockfd);//(int *)client_fd,修改成(int *)(long)client_fd(形参int* 是 8 字节,而实参 int client_fd却是 4 字节。为了避免这个警告变为long int 型)
while(1)
{
gets(send_buf);
if(send(sockfd,send_buf,strlen(send_buf),0)==-1)
{
perror("send error\n");
exit(1);
}
sleep(1);
}
close(sockfd);
pthread_cancel(id);
return 0;
}
参考Linux程序设计第三版(金..)