基于Linux的socket编程的聊天室设计.docx
- 文档编号:667436
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:15
- 大小:209.17KB
基于Linux的socket编程的聊天室设计.docx
《基于Linux的socket编程的聊天室设计.docx》由会员分享,可在线阅读,更多相关《基于Linux的socket编程的聊天室设计.docx(15页珍藏版)》请在冰点文库上搜索。
基于Linux的socket编程的聊天室设计
TCP/IP实验报告
基于Linux的socket编程的聊天室设计
2014/1/16
一、实验目的
基于Socket套接口,实现聊天程序的设计与实现,增强程序编写能力,了解基于socket的程序设计方法,加深对计算机网络通信的理解。
另外,通过课程设计培养自己严谨的科学态度,认真的工作作风、团队协作精神、自主设计和独力思考的能力。
二、实验原理
实验中,客户应用程序向服务器程序请求服务。
服务进程一直处于休眠状态,直到一个客户向这个服务的地址提出了连接请求。
在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。
客户端部分:
1.手动输入服务器端IP地址和端口号进行连接
2.发送消息给服务器端并显示服务器端回传的消息
3.监控连接状态,客户离开或故障时从列表中删除相应表项,并及时更新连接表。
服务器端部分:
1.手动建立服务器端与客户端的连接请求
2.把用户输入的信息及时发送到服务端,同时准备好接受,并显示信息。
3.在用户退出时关闭连接并保存聊天记录。
客户端-服务器端架构:
相关函数:
socket()函数:
intsocket(intfamily,inttype,intproto);
1)family指定protocolfamily(PF_INET对应TCP/IP).
2)type指定服务类型(SOCK_STREAM,SOCK_DGRAM).
3)protocol指定协议(通常0,代表缺省值).
bind()函数:
给socket绑定一个地址.
intbind(intsockfd,
conststructsockaddr*myaddr,
socklen_taddrlen);
bind返回值
listen()函数:
accept()函数:
intaccept(intsockfd,structsockaddr*cliaddr,socklen_t*addrlen);
sockfd是被动模式的TCPsocket.
cliaddr指针,指向一个已分配好的空间.返回客户地址.
addrlen是一个value-result参数
必须设置为cliaddr的空间大小
返回时,将被设置为使用cliaddr的空间大小.。
LINUX简介:
Linux操作系统是UNIX操作系统的一种克隆系统。
它诞生于1991年的10月5日。
由于Linux是开源和免费的,得到了广大计算机爱好者全力支持,现已成为今天世界上使用最多的一种UNIX类操作系统。
其具有的特点有:
开放性:
指系统遵循世界标准规范,特别是遵循开放系统互连(OSI)国际标准。
多用户:
是指系统资源可以被不同用户使用,每个用户对自己的资源(例如:
文件、设备)有特定的权限,互不影响。
多任务:
它是指计算机同时执行多个程序,而且各个程序的运行互相独立。
良好的用户界面:
Linux向用户提供了两种界面,用户界面和系统调用。
Linux还为用户提供了图形用户界面,它利用鼠标、菜单、窗口、滚动条等设施,给用户呈现一个直观、易操作、交互性强的友好图形化界面。
设备独立性:
是指操作系统把所有外部设备统一当作成文件来看待,只要安装它们的驱动程序,任何用户都可以像使用文件一样,操纵、使用这些设备,而不必知道它们的具体存在形式。
Linux是具有设备独立性的操作系统,它的内核具有高度适应能力,提供了丰富的网络功能,完善的内置网络是Linux一大特点。
安全性:
Linux采取了许多安全技术措施,包括对读、写控制、带保护的子系统、审计跟踪、核心授权等,这为网络多用户环境中的用户提供了必要的安全保障。
良好的可移植性:
是指将操作系统从一个平台转移到另一个平台,它仍然能按其自身的方式运行的能力。
Linux是一种可移植的操作系统,能够在从微型计算机到大型计算机的任何环境中和任何平台上运行。
TCP简介:
TCP与UDP同为传输层协议。
本系统采用的传输协议TCP协议。
TCP协议提供的是可靠的、面向连接的传输控制协议,即在传输数据前要先建立逻辑连接,然后再传输数据,最后释放连接3个过程。
TCP提供端到端、全双工通信;采用字节流方式,如果字节流太长,将其分段;提供紧急数据传送功能。
TCP协议主要特点:
1、面向连接的传输;2、端到端的通信;3、高可靠性,确保传输数据的正确性,不出现丢失或乱序;4、全双工方式传输;5、采用字节流方式,即以字节为单位传输字节序列;6、紧急数据传送功能;
三、实验实现
//--------------------------------server.c--------------------------------------------------
//包含工程所需的头文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definePERMS_IRUSR|S_IWUSR
#defineMYPORT3490
#defineBACKLOG10
#defineWELCOME"|----------Welcometothechatroom!
----------|"
voiditoa(inti,char*string)
{
intpower,j;
j=i;
for(power=1;j>=10;j/=10)
power*=10;
for(;power>0;power/=10)
{
*string++='0'+i/power;
i%=power;
}
*string='\0';
}
voidget_cur_time(char*time_str)
{
time_ttimep;
structtm*p_curtime;
char*time_tmp;
time_tmp=(char*)malloc
(2);
memset(time_tmp,0,2);
memset(time_str,0,20);
time(&timep);
p_curtime=localtime(&timep);
strcat(time_str,"(");
itoa(p_curtime->tm_hour,time_tmp);
strcat(time_str,time_tmp);
strcat(time_str,":
");
itoa(p_curtime->tm_min,time_tmp);
strcat(time_str,time_tmp);
strcat(time_str,":
");
itoa(p_curtime->tm_sec,time_tmp);
strcat(time_str,time_tmp);
strcat(time_str,")");
free(time_tmp);
}
key_tshm_create()
{
key_tshmid;
//shmid=shmget(IPC_PRIVATE,1024,PERM);
if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
{
fprintf(stderr,"CreateShareMemoryError:
%s\n\a",strerror(errno));
exit
(1);
}
returnshmid;
}
intbindPort(unsignedshortintport)
{
intsockfd;
structsockaddr_inmy_addr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(port);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),0);
if(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1)
{
perror("bind");
exit
(1);
}
printf("bingsuccess!
\n");
returnsockfd;
}
intmain(intargc,char*argv[])
{
intsockfd,clientfd,sin_size,recvbytes;
pid_tpid,ppid;
char*buf,*r_addr,*w_addr,*temp,*time_str;//="\0";
structsockaddr_intheir_addr;
key_tshmid;
shmid=shm_create();//创建共享存储区
temp=(char*)malloc(255);
time_str=(char*)malloc(20);
sockfd=bindPort(MYPORT);//绑定端口
while
(1)
{
if(listen(sockfd,BACKLOG)==-1)//在指定端口上监听
{
perror("listen");
exit
(1);
}
printf("listening......\n");
if((clientfd=accept(sockfd,(structsockaddr*)&their_addr,&sin_size))==-1)//接收客户端连接
{
perror("accept");
exit
(1);
}
printf("acceptfrom:
%d\n",inet_ntoa(their_addr.sin_addr));
send(clientfd,WELCOME,strlen(WELCOME),0);//发送问候信息
buf=(char*)malloc(255);
ppid=fork();
if(ppid==0)
{
//printf("ppid=0\n");
pid=fork();
while
(1)
{
if(pid>0)
{
memset(buf,0,255);
if((recvbytes=recv(clientfd,buf,255,0))<=0)
{
perror("recv1");
close(clientfd);
raise(SIGKILL);
exit
(1);
}
//writebuf'sdatatosharememory
w_addr=shmat(shmid,0,0);
memset(w_addr,'\0',1024);
strncpy(w_addr,buf,1024);
get_cur_time(time_str);
strcat(buf,time_str);
printf("%s\n",buf);
}
elseif(pid==0)
{
sleep
(1);
r_addr=shmat(shmid,0,0);
if(strcmp(temp,r_addr)!
=0)
{
strcpy(temp,r_addr);
get_cur_time(time_str);
strcat(r_addr,time_str);
if(send(clientfd,r_addr,strlen(r_addr),0)==-1)
{
perror("send");
}
memset(r_addr,'\0',1024);
strcpy(r_addr,temp);
}
}
else
perror("fork");
}
}
}
printf("------------------------------\n");
free(buf);
close(sockfd);
close(clientfd);
return0;
}
//-----------------------------client.c----------------------------------------#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
intmain(intargc,char*argv[])
{
structsockaddr_inclientaddr;
pid_tpid;
intclientfd,sendbytes,recvbytes;
structhostent*host;
char*buf,*buf_r;
if(argc<4)
{
printf("usage:
\n");
printf("%shostportname\n",argv[0]);
exit
(1);
}
host=gethostbyname(argv[1]);
if((clientfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket\n");
exit
(1);
}
clientaddr.sin_family=AF_INET;
clientaddr.sin_port=htons((uint16_t)atoi(argv[2]));
clientaddr.sin_addr=*((structin_addr*)host->h_addr);
bzero(&(clientaddr.sin_zero),0);
if(connect(clientfd,(structsockaddr*)&clientaddr,sizeof(structsockaddr))==-1)
{
perror("connect\n");
exit
(1);
}
buf=(char*)malloc(120);
memset(buf,0,120);
buf_r=(char*)malloc(100);
if(recv(clientfd,buf,100,0)==-1)
{
perror("recv:
");
exit
(1);
}
printf("\n%s\n",buf);
pid=fork();
while
(1)
{
if(pid>0){
//get_cur_time(time_str);
strcpy(buf,argv[3]);
strcat(buf,":
");
memset(buf_r,0,100);
//gets(buf_r);
fgets(buf_r,100,stdin);
strncat(buf,buf_r,strlen(buf_r)-1);
//strcat(buf,time_str);
//printf("---%s\n",buf);
if((sendbytes=send(clientfd,buf,strlen(buf),0))==-1)
{
perror("send\n");
exit
(1);
}
}
elseif(pid==0)
{
memset(buf,0,100);
if(recv(clientfd,buf,100,0)<=0)
{
perror("recv:
");
close(clientfd);
raise(SIGSTOP);
exit
(1);
}
printf("%s\n",buf);
}
else
perror("fork");
}
close(clientfd);
return0;
}
四、相关截图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 Linux socket 编程 聊天室 设计