网络聊天程序是目前应用极为广泛的一种网络软件,对于方便人们的交流沟通非常有效,同时,作为一种典型的网络应用,编写网络聊天程序是学习基于Linux的网络编程的有效方法。
结合任务需求设计该程序,程序采用多线程方式实现不同主机之间的通信。除满足基础要求之外,还考虑到通信私密性及多用户的问题,程序通过上锁和解锁,实现公开通信和隐秘通信两种通信方式,客户端输入用户名即可进入隐秘通信模式,输入ALL返回公开通信模式,默认使用公开通信;通过设置用户名变量,实现多用户同时通信,在实现多用户功能的同时,用户过多输入会使数据溢出,因此设置用户上限以解决此问题,某一客户端退出并不影响其他客户的使用,所有用户全部退出,服务器关闭端口,结束进程。
程序基于Linux系统开发,纯C语言Socket实现多个客户端之间通信,由服务器端进行数据处理,基本实现聊天功能的基础运用。
目录
1 设计目的
2 设计思路
2.1 服务器主线程程序框架
2.2 服务器连接客户接发信息框架
2.3 客户端主线程程序框架
2.4 客户端信息接发程序框架
3 设计测试
3.1 公开通信模式
3.2 隐秘通信模式
4 主要代码
4.1 客户端主函数代码
4.2 服务器主函数代码
在使用Linux线程和Socket接口的基础上,编写网络聊天程序,从而掌握Linux应用程序开发的基本方法,练习Linux线程及Socket编程的方法。
图2.1 服务器主线程程序框图
图2.2 服务器连接客户接发信息框图
图2.3 服务器连接客户接发信息框图
图2.4 服务器连接客户接发信息框图
模拟四个用户同时在线通信,分别自命名用户1、用户2、用户3和用户4。
图3.1 服务器端显示内容图
图3.2 客户端显示内容图
公开通信模式下,由任意用户发送信息,其余用户会同时收到信息内容:
图3.3 用户1发送消息效果图
图3.4 用户2发送消息效果图
隐秘模式下用户输入接收信息用户名称得以实现该用户至目标用户单向信息隐秘通信,另一方若需要隐匿通信需要输入该用户名称,实现双向信息隐秘通信。
图3.5 用户1向用户2隐秘通信效果图
图3.6 用户2回应用户1信息效果图
图3.7 用户3和用户4之间进行双向隐秘通信效果图
int main(int argc, char* argv[])
{
//创建套接字文件,返回套接字文件描述符 socket()
sockfd = socket(AF_INET, SOCK_STREAM, 0);
pthread_t tid;
if (sockfd == -1)
{
perror("socket create failure\r\n");
return 0;
}
//创建结构,初始化数据 struct sockaddr 使用 struct sockaddr_in
SIN ser_addr;
ser_addr.sin_family = AF_INET; //选择ipv4协议族
ser_addr.sin_port = htons(PORT); //端口号要转换端绪,从小端绪转换从大端绪
ser_addr.sin_addr.s_addr = inet_addr(IP); //十进制的字符ip转换成网端数据格式 服务端IP
int len = sizeof(ser_addr);
if (connect(sockfd, (SA*)&ser_addr, len) == -1)
{
perror("connect failure\r\n");
return 0;
}
else
{
printf("WELCOME TO DADONG TALK ROOM!\r\n");
printf("Please sign you name:");
char temp[20] = { 0 };
memset(temp, 0, 100);
scanf("%s", temp);
send(sockfd, temp, strlen(temp), 0); //发送信息
pthread_create(&tid, NULL, message, NULL);
}
char wbuf[100] = { 0 };
while (1)
{
memset(wbuf, 0, 100);
read(0, wbuf, 100);
if (strncmp(wbuf, "quit", 4) == 0)
{
send(sockfd, wbuf, strlen(wbuf), 0);
final = 1;
close(sockfd);
return 0;
}
send(sockfd, wbuf, strlen(wbuf), MSG_NOSIGNAL);
memset(wbuf, 0, 100);
usleep(20);
}
close(sockfd);
return 0;
}
int main(int argc, char* argv[])
{
//创建套接字文件,返回套接字文件描述符 socket()
pthread_mutex_init(&mm, NULL);
pthread_t CON;
pthread_create(&CON, NULL, user_connect, NULL); //分配连接的线程
sleep(30); //30s等待连接
while (count != user);
printf("-------**********************************-------\n");
printf("-------WELCOME JOIN DADONG TALK ROOM AGAIN-------\n");
//关闭文件描述符 close()
close(sockfd);
return 0;
}