现在的位置: 首页 > 综合 > 正文

局域网聊天室

2016年12月10日 ⁄ 综合 ⁄ 共 3328字 ⁄ 字号 评论关闭

最近学习网络编程,写了一个聊天室,基本功能已经实现,还有待优化的部分

服务器端

#include"server.h"
static int sockid,i,end;
void fa(int signo)
{
	printf("\r服务器正在关闭>>>>>\n");
	sleep(2);
	close(sockid);
	exit(0);
}
typedef struct
{
	struct sockaddr_in c_sockaddr;
	int c_sockid;
	pthread_t tid;
}c_addr;
//建立套接字绑定端口
int s_bind(void);
int s_pthread_create(int sockid);
void * task(void *p);

int main(int argc,char * agrv[])
{
	printf("服务器开始运行\n");
	//信号处理
	signal(2,fa);
	//建立套结字,绑定借口
	int sockid = s_bind();
	if(-1 == sockid)  
		printf("建立绑定套结字失败\n");		
	//开始监听客户端
	listen(sockid,100);
	//为客户端分配线程
	s_pthread_create(sockid);
	//exit(0);
	exit(0);
}
int s_bind(void)
{
	//生成套结字
	 sockid = socket(AF_INET,SOCK_STREAM,0);
	//准备地址信息
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//绑定服务短地址
	int res = bind(sockid,(struct sockaddr *)&addr,sizeof(addr));
	if(res == -1)
	{
		perror("bind"),exit(-1);;
	}
	return sockid;
}

int s_pthread_create(int sockid)
{
	//定义结构题,用于存储客户端的地址与通信编号
	c_addr c_c_addr[100];
	while(i < 100){
		//初始化c_c_addr
		c_c_addr[i].c_sockid = 0;
	//准备套结字接收客户端地址
	socklen_t len = sizeof(c_c_addr[i].c_sockaddr);
	//接受到客户端信息
	c_c_addr[i].c_sockid = accept(sockid,(struct sockaddr *)&c_c_addr[i].c_sockaddr,&len);
	if(c_c_addr[i].c_sockid == -1)
		perror("accept"),exit(-1);
		//分配线程
		//pthread_t tid;
		
		printf("客户端:%s上线\n",inet_ntoa(c_c_addr[i].c_sockaddr.sin_addr));
		pthread_create(&c_c_addr[i].tid,NULL,task,(void *)c_c_addr);
		usleep(500000);
		i++;
	}
}
void * task(void *p) 
{
	int n = i;
		c_addr * c_c_addr = p;
     //接收客户端发来的消息
	 char buf[100] = {0};
	 while(1)
	 {

		printf("n == %d\n",n);
	 	if(0 >= read(c_c_addr[n].c_sockid,buf,sizeof(buf)))
		{				
				c_c_addr[n].c_sockid = -1;
				printf("客户端:%s下线\n",inet_ntoa(c_c_addr[n].c_sockaddr.sin_addr));
				pthread_exit(&c_c_addr[n].tid);
		}
		printf("来自客户端的消息%s\n",buf);
		char *p = buf;
		//转发给其他客户端
		int j = 0;
		while(j < i)
		{
			//判断是否是自己线程,
			if(c_c_addr[j].tid == pthread_self() || c_c_addr[j].c_sockid == -1)
			{
				j++;
				continue;
			}
			if(0 >= send(c_c_addr[j].c_sockid,buf,strlen(buf) + 1,0))
			{
				c_c_addr[j].c_sockid = -1;
			}
			j++;
		}
	 //推出线程
	 }	
}

客户端

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<semaphore.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<pthread.h>
#include<unistd.h>
#define PORT 8888
int sockid;
void fa(int signo)
{
	printf("\r客户端马上关闭\n");
	close(sockid);
	sleep(1);
	exit(0);
}
int c_connect(void);
void scan(char arr[]);
void talk(void);
void *task(void *p);
void speak(char *name);
int main()
{
	signal(2,fa);
	//与服务器建立链接
	 sockid = c_connect();
	//输入用户昵称
	char name[20];
	printf("请输入用户姓名\n");
	scanf("%s",name);
        //接收服务器发来的消息
        talk();
        //吧用户输入的信息发送给服务器端
        speak(name);	
}
void speak(char *name)
{
	while(1)
	{
		//sleep(1);
		printf("请输入信息:\n");
		char cuf[100];
		fflush(stdin);
		//scanf("%*[^\n]");
		//scanf("%*c");
		//fwrite(cuf,1,1,stdin);
		scanf("%s",cuf);
	//	fgets(cuf,100,stdin);
		fflush(stdin);
		//cuf[strlen(cuf)-1] = '\0'; 
		char buf[1000];
		sprintf(buf,"%s:%s",name,cuf);
		int res;
		if( 0 >= send(sockid,buf,strlen(buf) + 1,0))
			//printf("res = %d\n",res);
			perror("服务器关闭"),exit(-1);
	}
}
void *task(void *p)
{
	char buf[100];
	while(1)
	{
		if(0 > recv(sockid,buf,sizeof(buf),0))
			perror("recv"),exit(0);
		printf("%s\n",buf);
	}
}
void talk(void)
{
	//创建线程用于接受服务器的消息
	pthread_t tid;
	pthread_create(&tid,NULL,task,NULL);
}
void scan(char arr[])
{
	printf("请输入用户昵称\n");
	scanf("%s",arr);
	fflush(stdin);
}
int c_connect(void)
{
	int sockid = socket(AF_INET,SOCK_STREAM,0);
	//准备服务器的地址信息
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//链接服务器地址
	int res = connect(sockid,(struct sockaddr*)&addr,sizeof(addr));
	if(-1 == res)
	{
		perror("connect"),exit(-1);
	}
	return sockid;
}

抱歉!评论已关闭.