闲暇之余,利用linux下的多线程和网络知识,写了个简单多人聊天程序,意在说明用GNU C写网络类程序的步骤和需要注意的问题以及linux多线程的使用方法。
编译:
gcc -Wall -o server -lpthread server.c
gcc -Wall -o client -lpthread client.c
服务器端:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
//定义同时聊天的人数
#define COUNT 5
//保存socket
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+1]='\0';
while(1){
if((recvbytes = recv(client_fd, buf, 1024, 0))==-1){
perror("recv error");
exit(1);
}
if(recvbytes==0){
printf("%sbye!\n",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");
exit(1);
}
}
}
}
//断开时关闭socket,并将描述符值置为-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(){
//初始化socket数组
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(12345);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//绑定
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("bind");
exit(1);
}
//监听
if(listen(sockfd,10)==-1){
perror("listen");
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");
exit(1);
}
//找到一个可用的socket位置
while(socket_fd[i]!=-1)
i=(i+1)%COUNT;
//保存socket并启动线程处理
socket_fd[i]=client_fd;
pthread_create(&id,NULL,(void *)pthread_function,(int *)client_fd);
}
}
客户端:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
char recv_buf[1500],send_buf[1024];
//线程入口函数,负责显示接收到的信息
void pthread_function(int sockfd){
int recvbytes;
while(1){
if((recvbytes = recv(sockfd, recv_buf, 1500, 0))==-1){
perror("recv error");
exit(1);
}else{
recv_buf[recvbytes]='\0';
printf("%s\n", recv_buf);
}
}
}
int main(void){
pthread_t id;
int sockfd;
struct sockaddr_in server_addr;
//参数设置
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1){
perror("socket error");
exit(1);
}
//连接
if(connect(sockfd, (struct sockaddr*)&server_addr,sizeof(server_addr))==-1){
perror("connect error");
exit(1);
}
//输入客户端名字
char name[20];
printf("input your name:");
scanf("%s",name);
send(sockfd,name,strlen(name),0);
pthread_create(&id,NULL,(void *)pthread_function,(int *)sockfd);
while(1){
gets(send_buf);
if(send(sockfd,send_buf,strlen(send_buf),0)==-1){
perror("send error");
exit(1);
}
sleep(1);
}
//关闭socket并取消线程
close(sockfd);
pthread_cancel(id);
return 0;
}
分享到:
相关推荐
基于 Linux 网络聊天室的设计实用文档 基于 Linux 网络聊天室的设计实用文档是《Linux 操作系统》课程设计报告的一部分,该文档的目的是为了设计一个基于 Linux 平台的网络聊天室。该设计主要分为两部分,客户端...
在Linux环境下实现网络聊天室,主要涉及以下技术: 1.2.1 网络套接字(Socket) 网络套接字是进程间通信的一种方式,尤其适合网络通信。在聊天室中,服务器端通过监听套接字等待客户端的连接请求,客户端则通过...
在Linux下的网络聊天室中,Socket接口被用于建立客户端与服务器之间的连接,实现数据传输。 3. **TCP/IP协议**:TCP(传输控制协议)和IP(网际协议)是互联网上最常用的通信协议。TCP负责可靠的数据传输,IP则负责...
本项目通过详细分析了在Linux环境下实现网络聊天室的关键技术和设计思路。从需求分析、总体设计到详细设计,每个环节都进行了深入探讨。使用C语言和Socket编程技术,结合多线程机制,成功构建了一个稳定、高效的网络...
2. 基于JAVA的聊天室:利用Java Applet与服务器端的聊天服务器程序交互,实现实时性。然而,Java虽然跨平台,但在处理中文文本时可能存在编码问题,导致乱码。 【基于PHP的网络聊天室系统】 PHP编写聊天室系统时,...
【标题】: "用PHP实现Web...同时,这种技术对于实时性要求高的应用,如聊天室、在线游戏或实时数据显示,具有显著优势。由于减少了不必要的页面跳转,不仅可以提高页面加载速度,还能减少服务器负载,提高系统效率。
将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示...
1. **基于TCP的网络聊天室项目**: - **技术栈**:主要采用C语言、Socket编程、多线程技术和Signal信号机制。 - **应用场景**:适用于局域网内的即时通信。 - **关键点**:Socket编程实现数据传输、多线程技术...
公开聊天室: : Wiki: : 执照 该程序根据GNU通用公共许可证授权。 有关更多信息,请参见文件。 描述 EiskaltDC ++是一个跨平台程序,使用(DC,又称NMDC)和(ADC)协议。 它与DC ++,AirDC ++,FlylinkDC ++和...
为了帮助用户更好地使用GCC,手册中还提供了获取帮助的各种途径,包括在线文档、邮件列表、IRC聊天室等。 #### 十三、为GCC开发做贡献 最后,手册鼓励有能力的开发者参与到GCC的开发中来,贡献自己的力量,共同推动...
- **GNU**:Ubuntu采用了大量的GNU工具和软件,因此也被视为GNU/Linux的一部分。 - **获得Ubuntu**: - 通过官方网站下载ISO镜像文件进行安装。 - 可以选择使用Live CD/DVD或USB启动盘来体验Ubuntu而无需安装。 ...