客户端
#include<stdlib.h>
#include<sys/types.h>
#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
void sent(int *qian){
int q=*qian;
char buff[1024];
int len;
while(1){
bzero(buff,1025);
fgets(buff,1024,stdin);
//
len=send(q,buff,30,0);
if(len<0){
perror("send ");
break;
}
if(!strncasecmp(buff,"quit",4)){
printf("I will quit!\n");
break;
}
}
close(q);
pthread_exit(NULL);
}
int main(){
int lian,len;
char buff[30];
struct sockaddr_in dest;
if((lian=socket(AF_INET,SOCK_STREAM,0))<0){
printf("socket error!\n");
return -1;
}
printf("socket created\n");
bzero(&dest,sizeof(dest));
dest.sin_family=AF_INET;
dest.sin_port=htons(8088);
inet_aton(("127.0.0.1"),(struct in_addr*)&dest.sin_addr.s_addr);
if(connect(lian,(struct sockaddr *)&dest,sizeof(dest))==-1){
perror("connect ");
exit(1);
}
printf("sercer connect\n");
pthread_t sended;
pthread_create(&sended,NULL,(void*)sent,&lian);
while(1){
bzero(buff,30);
len=recv(lian,buff,30,0);
if(len<=0){
perror("recv ");
break;
}
else if(len>0)printf("%s\n",buff);
else {
printf("the other one close,quit\n");
break;
}
}
pthread_join(sended,NULL);
//等待sended线程结束之后,主线程才能结束
close(lian);
return 0;
}
服务端
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <time.h>
#include<errno.h>
int num=0;
int new_fd[5];
struct sockaddr_in myaddr,itaddr;
void sended(int *qian){
char buf[30];
int len;
int q=*qian;
char mass[60];
len=sizeof(struct sockaddr);
while(1){
if((recv(q,buf,30,0))<=0){
//接收来自客户端的消息
break;
}
if(strncasecmp(buf,"quit",4)==0){
printf("%d已退出聊天室\n",q);
close(q);
break;
}
printf("%d说:%s\n",q,buf);
sprintf(mass,"%d说:%s",q,buf);
int j=0;
for(j=0;j<num;j++){
if(q-4!=j)
send(new_fd[j],mass,60,0);
}
//将某个客户端的信息发送给其它客户端
bzero(buf,30);
}
printf("接受信息结束!\n");
close(q);
pthread_exit(NULL);
}
void revied(int *qian){
int fd;
int q=*qian;
while(1){
char buf[1024];
char rizhi[100];
int fang;
int len;
len=sizeof(struct sockaddr);
bzero(buf,1025);
time_t t;
t=time((time_t *) 0);
//得到系统时间
if((fang=accept(q,(struct sockaddr *)&itaddr,&len))<0){
//接收来自客户端的连接申请
printf("accept error!\n");
exit(1);
}
else printf("server:gor connection from %s ,port %d,socket %d ,time:%s\n",inet_ntoa(itaddr.sin_addr),ntohs(itaddr.sin_port),fang, ctime(&t));
//打印出客户端连接信息
//将信息写入文件
sprintf(rizhi,"the %d user connection from %s ,port %d,socket %d ,time:%s\n",num+1,inet_ntoa(itaddr.sin_addr),ntohs(itaddr.sin_port),fang, ctime(&t));
fd =open("rizhi.txt",O_RDWR|O_CREAT, S_IRWXU);
lseek(fd,0,SEEK_END);
write(fd,rizhi,strlen(rizhi));
close(fd);
new_fd[num]=fang;
num++;
printf("连接了%d用户\n",num);
pthread_t sent;
pthread_create(&sent,NULL,(void*)sended,&fang);
//线程sended函数
sleep(0.2);
}
close(q);
pthread_exit("线程安全退出!\n");
}
int main(){
int i=1;
int lian;
int pid,len;
char buf[1024];
pthread_t revi;//声明线程ID
printf("Socket...\n");
lian=socket(AF_INET, SOCK_STREAM, 0);
/*
创建套接字完成连接,
第一个参数为地址族,也就是ip地址类型,AF_INET表示地址类型为ipv4
第二个参数为数据传输方式/套接字类型,SOCK_STREAM表示流格式套接字/面向连接的套接字
第三个参数为传输协议,设为0,则系统会自动推演该使用什么传输协议
socket()函数返回文件描述符,唯一标识套接字
*/
if(lian<0){
printf("%s\n","socket error!");
exit(1);
}
printf("Bind...\n");
myaddr.sin_family=AF_INET;
myaddr.sin_port=htons(8088);
//初始化sockaddr_in结构体参数
//sin_port存储端口号
//htons()将本地字节顺序转换为网络字节顺序
inet_aton(("127.0.0.1"),(struct in_addr*)&myaddr.sin_addr.s_addr);
//inet_aton,将一个字符串ip转换为网络序列ip地址
if(bind(lian,(struct sockaddr*)&myaddr,sizeof(myaddr))<0)
//bind(),创建本地捆绑
{
printf("Bind failed.\n");
exit(1);
}
printf("listen...\n");
listen(lian,5);
//linten()创建套接口并监听申请的连接
pthread_create(&revi,NULL,(void*)revied,&lian);
/*建立线程
第一个参数为指向线程标识符的指针
第二和参数设置线程属性
第三个参数为线程运行函数的起始地址
第四个参数为该运行函数的参数
*/
while(1){
int j=0;
char massage[30];
char ass[60];
scanf("%s",&massage);
sprintf(ass,"服务器说:%s",massage);
if(strncasecmp("quit",massage,4)==0){
printf("即将退出!\n");
break;
}
if(num<=0)printf("没有客户端连接!\n");
else{
for(j=0;j<num;j++){
int ss=send(new_fd[j],ass,60,0);
}
//服务器的自己写的信息发送给客户端
}
sleep(0.5);
}
pthread_join(revi,NULL);
//等待revi线程结束之后,主线程才能结束
close(lian);
return 0;
}