Linux Socket编程---TCP实现多客户端的网络聊天室

本程序实现的功能:

基于linux的网络聊天室

服务器端功能:

1)能够实现同时监听10个客户端

2)新的客户进入聊天室,发送新客户进入的系统消息给所有在线客户

3)在线客户实现基本的群聊功能

4)保存聊天记录,并支持查询聊天记录

5)可以通过终端查看客户之间的聊天状况

客户端功能:

1)能过正常连接服务器

2)通过多线程实现同时进行收发消息

3)保存客户本地聊天记录

4)可以查询本地聊天记录

 

tcpserver.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include
#include

//给线程传输的信息
struct threadinfo
{	
	//socket
	int my_sock;
	//随机分配的端口号
	int my_port; 
};

//用户数量
int usernum = 0;
//socket数组
int sock_array[10];
//打开文件
int fd;

//发送线程
void *recvsocket(void *arg)
{
	//接受结构体
	struct threadinfo *thread = arg;

	int st = thread->my_sock;
	int port = thread->my_port;
	char receivebuffer[100]; 
	int i;
	int n;
	int length = sizeof(sock_array)/sizeof(sock_array[0]);
	char sendbuffer[100];
	char writebuffer[100];
	
	while(1){
		//接受客户端传回的数据 
		memset(receivebuffer, 0, sizeof(receivebuffer)); 
		n = recv(st, receivebuffer, sizeof(receivebuffer), 0);
		//判断通信是否结束 
		if(n <= 0)
			break;
		printf("来自%d的数据:%s\n", port,receivebuffer);

		//将接受到的聊天记录保存到文件中
		memset(writebuffer, 0, sizeof(writebuffer));
		sprintf(writebuffer,"%d",port);
		strcat(writebuffer,":");
		strcat(writebuffer,receivebuffer);
		strcat(writebuffer,"\n");
		write(fd,writebuffer,sizeof(writebuffer));

		//将接受到的消息发送给出自己外的其他人
		memset(sendbuffer, 0, sizeof(sendbuffer));
		sprintf(sendbuffer,"%d",port);
		strcat(sendbuffer,"说:");
		strcat(sendbuffer,receivebuffer);
		for(i = 0; i

tcpclient.c

#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include
#include


//打开文件
int fd;
//客户端socket
int client_sock;
//文件路径
char path[100];
//段口号
char port[100];

//发送线程
void *sendsocket(void *arg)
{
	//接受socket
	int st = *(int *)arg;
	char sendbuffer[100]; 
	char writebuffer[100];
	while(1){
		//向服务器发送数据 
		memset(sendbuffer, 0, sizeof(sendbuffer)); 
		//printf("请输入消息:");
		scanf("%s",sendbuffer);
		memset(writebuffer, 0, sizeof(writebuffer)); 
		strcat(writebuffer,sendbuffer);
		strcat(writebuffer,"\n");
		//写入文件
		write(fd,writebuffer,sizeof(writebuffer));
		//发送消息
		send(st, sendbuffer, strlen(sendbuffer), 0); 
	}
	return NULL;
}

//接受线程
void *recvsocket(void *arg)
{
	int st = *(int *)arg;
	char receivebuffer[100]; 
	char writebuffer[100];
	int n; 
	while(1){
		//读取服务器传回的数据 
		memset(receivebuffer, 0, sizeof(receivebuffer));
		n = recv(st, receivebuffer, sizeof(receivebuffer), 0);  
		//用于判断通信是否结束 
		if(n<=0)
			break;		
		memset(writebuffer, 0, sizeof(writebuffer)); 
		strcat(writebuffer,receivebuffer);
		strcat(writebuffer,"\n");
		//写入文件
		write(fd,writebuffer,sizeof(writebuffer));
		//输出
		printf("%s\n", receivebuffer);
		
		
	}
	return NULL;
}

int main() { 

	//创建套接字 
	int sock = socket(AF_INET, SOCK_STREAM, 0); 
	//向服务器(特定的IP和端口)发起请求 
	struct sockaddr_in serv_addr; 
	memset(&serv_addr, 0, sizeof(serv_addr));//每个字节都用0填充 
	serv_addr.sin_family = AF_INET; 
	serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
	serv_addr.sin_port = htons(6666); 

	//连接服务器,成功返回0 
	client_sock = connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
	if(client_sock == 0) { 
		printf("服务器连接成功!\n"); 
	} 
	
	//新建一个结构体
	struct sockaddr_in client_addr; 
	memset(&client_addr, 0, sizeof(client_addr));

	int len = sizeof(client_addr);
	//获得本程序的sockaddr_in结构体
	int ti = getsockname(sock, (struct sockaddr*)&client_addr, &len);

	//对字符串拼接得到路径
	sprintf(port,"%d",client_addr.sin_port);
	strcat(path,"./usernote/");
	strcat(path,port);
	//打开文件
	fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_APPEND|O_NONBLOCK);
	if(fd == -1)
	{
		printf("失败!");
	}

	//创建发送接受两个线程  一个接受线程一个发送线程
	pthread_t thrd1, thrd2;
	pthread_create(&thrd1, NULL, sendsocket, &sock);
	pthread_create(&thrd2, NULL, recvsocket, &sock);
	pthread_join(thrd1, NULL);
	pthread_join(thrd2, NULL);

	//关闭文件
	close(fd);
	//关闭套接字 
	close(sock); 

	return 0; 

} 

 

你可能感兴趣的:(Socket编程,进程之间的通信)