版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式实验报告
班级:14级移动一班
学号:
姓名:蒋浩
一:实现三个客户端,分别简称客户端1,客户端2,客户端3.•…
客户端1实现向服务器发送字符串“name”
客户端2实现向服务器发送字符串“class”
客户端3实现向服务器发送字符串“id”
实现一个服务器程序,规定该服务器程序采用并发机制解决客户端发送过来的数据,具。
体规定如下:
服务器收到客户端1发送的字符串“name”后,给客户端1回复“蒋浩”
服务器收到客户端2发送的字符串“class”后,给客户端2回复“14级移动一班”
服务器收到客户端2发送的字符串“id”后,给客户端2回复“”
二:三个客户端分别收到服务器回复的数据后完毕以下操作:
1:客户端1把服务器回复的数据“蒋浩”传递给客户端2,然后等待客户端2发送信。号
SIGUSR1,假如客户端1收到该信号,则客户端R打印“dientover”字符串后结束
2:客户端2收到客户端1的数据后,给客户端1发送信号SIGUSR1,然后,客户端2把
。字符串“蒋浩-14级移动一班”发送给客户端3,发送成功后结束。
3:客户端3收到数据后把字符串“蒋浩-14级移动一班”写入到文献蒋浩一14级移动
一班,txt文献中
思错;
(1):客户端与服务器间通信:
程序通过socket编程实现,socket是在用户应用层和TCP/IP协议
通信层间的封装接口,简化操作,让用户通过socket来实现
2层间的操作,组织数据。
服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听
(listen),调用accept阻塞,等待客户端连接。
在这时假如有个客户端初始化一个Socket,然后连接服务器(connect),
假如连接成功,这时客户端与服务器端的连接就建立了。
客户端发送数据请求,服务器端接受请求并解决请求,然后把回应数据发送
给客户端,客户端读取数据,最后关闭连接,一次交互结束。
Linux网络通信通过套接字来进行编程的.程序通过socket和其它几个A
PI的调用,会返回一个通讯的文献描述符也就是socket,我们可以将这个描
述符当作普通的文献的描述符来操作,这就是linux的设备无关性的好处我们
可以通过向描述符读写操作实现网络之间的数据交流.
(2):客户端之间通信
两个客户端之间通信使用有名管道通信,管道通信是一个进程打开写端,一个
进程打开读端,然后才可以进行通信。假如只打开有名管道的一端系统则会阻塞
打开进程,知道有此外一个进程打开该管道的另一端,当前进程继续执行;
客户端1把服务器回复的数据名字传递给客户端2,等待接受客户端2发送的
信号,假如客户端1收到信号则结束,客户端1是以只读方式打开管道,然后写入
管道,客户端2以写的方式打开管道,接受到信息,然后客户端2以kill命令发
送信号kill(pid,SIGUSR1以告诉客户端1打印结束命令;
客户端2收到客户端1的数据后,给客户端1发送“SIGUSR1”信号,然后,
客户端2把字符串姓名和学号发送给客户端3,发送成功后结束,客户端2和3之
间的通信仍然是管道通信,由于客户端3还要将收到的信息存入文本文献,所以
客户端3以读写的方式打开管道进行通信open;最后客户端3将信息写入到文
本文献使用:write
原理:
一方面知道有三个客户端,一个服务器,所以服务器要采用并发式服务器才干接受多个客户端
的连接请求
(1)服务器设计思绪:
命令行参数设计
为了动态在命令行参数中输入端口,但命令行参数是字符串,端口是int型,所以要转化一下
Intmain(intargc,char*argv)
Main()函数设计
一个结构体存储客户端的信息
Structuser
(
Char[20]name;〃客户端名称
Char[100]message;〃客户端发送的消息
Intfd;〃客户端的套接字文献描述符
)
由于要同时解决多个连接请求的服务器程序,该程序定义一个intclient[3];用来存储客
户端连接的套接字描述符数组,初始化客户端连接描述符的值都为-1,代表空闲,当一个客
户端的发送连接请求时,从client日数组中找到一个值为-1(空闲)的来解决该客户端的连
接请求
While()
(
Client[O]=accept();//找到一个空闲套接字
Client[0]=1;〃该套接字被占用
〃针对当前套接字创建一个线程,对当前套接字的消息进行解决
pthread_create(ma1Ioc(sizeof(pthread_t)),NULL,(void*)(&mess
age_deal),(void*)connfd[i]);
)
线程体函数
Voidmessage_dea1(intfd)
(
Whi1e()
(
recv(connectfd,recvbuf,1000,0)//接受客户端发来的
send(connectfd,user_news,strlen(user_news)+l,0);//向客户端回复数据
)
)
要实现以下服务器回复客户端消息的功能......
服务器收到客户端1发送的字符串“name”后,给客户端1回复“蒋浩”
服务器收到客户端2发送的字符串“class”后,给客户端2回复“14级移动一班”
服务器收到客户端2发送的字符串“id”后,给客户端2回复“”
我采用的是服务器收到客户端发来的消息后用if()语句检查一下消息内容是什么?
假如是"name"回复“蒋浩”
等等..........
(2)客户端设计思绪:
Main()函数
在主函数中创建一个线程,主线程用来接受服务器回复的数据,新的线程用来向服务器发送数
据
〃创建发送消息的线程,调用了发送消息的函数send_message
pthread_create(&threadl,NULL,(void*)(&send_message),NULL);
while(1)//把经服务器解决后的消息打印出来
。recv(1d,buff,l000,0)
)
发送消息线程
voidsend_message()
(
=While(l)
send(ld,news,strlen(news)+l,0);
)
Server服务器client客户端,
碰到的国难;
第一部分在完毕的时候没有困难,就是客户端和服务器通信,在第二部分中开始不知道客户端
进程之间怎么进行通信,为了实现两个毫不相关的进程间通信,上网查了一些方法
方法一:有名管道
方法二:消息队列
1:服务器回复的数据“蒋浩”
客户端1客户端2
2:发送SIGUSR1信号|客户端3
3:把字符串“蒋浩-14
级移动一班”发送给客户端
3
解决方法:
1:客户端1--->客户端2采用消息队列
2:客户端2--->客户端3采用有名管道
在客户端2和客户端3之间加入有名管道进行通信
次白岭->
intfd2;
if((fd3=open("kkk"zO_RDONLY))<0)
mode]mode=O_NONBLOCK;
//
(
if((mkfifo("kkk"zmode))<0)
perror(Hopen");
(
perror(Hfailedtomkfifo");
exit⑴;
exit(l);
}
1
while((len3=read(fd3,buf3,BUFES))>0)
printf("read:%s\n",buf3);
close(fd3);
charbuffl_v[]="蒋浩」4级移动1班二,;
intfdl_v;
intlenl_v=strlen(buffl_v);
if((fdl_v=open("/root/蒋浩
代砾,
Server:
#inc1ude<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#inc1ude<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<arpa/inet.h>
intPORT;
structuser_message
(
charname[20];
charmessage[100];
intconnfd;〃套接字描述符
}user[10];
〃全局变量
int1d;//监听套接字
imconnfd[10];〃分别记录多个客户端的套接字
chararray[100];〃字符串缓冲区
intnum=0;
voidmessage_deal(intconnectfd);〃服务器对当前套接字的消息进行解决的函数
voidquit();
intmain(intargc,char*argv[])
(
intAJ;
intN=1000;
intSUM=0;
for(I=0;l<4;l++)
{
A=(int)argv[1][l]-48;
dA=A*N;
66N=NA0;
O,SUM=SUM+A;
)
//printf("%d*',SUM);
PORT=SUM;
§pthread_tthread;
dstructsockaddr_incin;
structsockaddr_insin;
charaddr_p[1000];〃地址缓冲区
®sock1en_tlen;
//创建套接字
print*"Sock
ld=socket(AF」NET,SOCK_STREAM,0);
,〃初始化网络通信地址结构体变量
bzero(&sin9sizeof(sin))/
dsin.sin_family=AF_INET;
sin.sin_port=htons(PORT);
sin.sin_addr.s_addr=INADDR_ANY;
〃把套接字帮定到初始化的地址结构上
6printf(nBind...");
bind(1d,(structsockaddr*)&sin,sizeof(sin));
"/开始监听
dprintf("1istening...\n
listen(Id,10);
〃创建一个线程,对服务器程序进行管理(关闭)
pthread_create(&thread,NULL,(void*)(&quit),NULL);
//记录空闲的客户端的套接字描述符(-1为空闲)
inti=0;
for(i=0;i<10;i++)〃套接字描述符都初始化为空闲
(
»connfd[i]=1;
)
»charbuff[500];〃字符串缓冲区
while(1)
(
1en=sizeof(cin);
for(i=0;i<10;i++)//找到一个空闲的套接字描述符
(
if(connfd[i]==-l)
(
obreak;
)
)
〃调用accept从1isten接受的连接队列中取得一个连接
connfd[i]=accept(ld9(struetsockaddr*)&cin,&1en);
针对当前套接字创建一个线程,对当前套接字的消息进行解决
pthread_create(ma1loc(sizeof(pthread_t)),NULL,(void*)(&message_dea
1),(void*)connfd[i]);
num++;
)
return0;
)
voidmessage_deal(intconnectfd)//线程体函数,
(
charrecvbuf[50。];//接受到的字符串缓冲区
charname;
。intufd;
charu_name[40];
。intt=connectfd;
recv(t,u__name,l000,0);
dprintf(M%sjoinin\n\nM,u_name);
strcpy(user[num].name,u_name);
userEnum].connfd=connectfd;
while(1)
9
。intLen;
oLen=recv(connectfd,recvbuf,1000,0);//接受客户端发来的消息。下面考
虑是群发还是私发
?intlen;
alen=strlen(recvbuf);
,charuser_news[]="蒋浩”;
,charuser_news11]=H14移动一班”;
charuser_news2[]
。recvbuf[Len]=,\0';
66if(strcmp(recvbuf,"name")::。)//假如收到消息"name",就恢复"蒋浩”
'(
,send(connectfd,userenews,strlen(user_news)+1,0);
printf(已发送字符串%s成功H,userenews);
}
if(strcmp(recvbuf/'classn)==O)〃假如收到消息“dass“,就恢复”14移动一班,,
send(connectfd,user_newsl,strlen(user_newsl)+1,0);
ooprintf("已发送字符串%s成功”,user_newsl);
od}
if(stremp(reevbuf,"id")==0)//假如收到消息nname",就恢复
mt.
o{send(conneetfd,user_news2,str1en(user_news2)+l,0);
叩rintf("已发送字符串%s成功”,user_news2);
d}0
)
voidquit()
(
charmsg[10];
whi1e(l)
(
seanf("%s",msg);
if(strcmp("quit'\msg)==0)
(
printf(HByebye...\n
cIose(Id);
exit(O);
)
}
Client1.c
#inc1ude<stdio.h>
#include<std1ib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#inelude<pthread.h>
#inc1ude<sys/types,h>
#include<sys/ipc.h>
#inelude<sys/msg.h>
#incIude<signal.h>
#defineSIZE10
#defineSERVERJP"127.0.0」“//服务器端IP
intPORT;
intId;
voidsend_message();
voidsingle();
structmsgbuf
longmtype;
charmtext[SIZE];
);
voidhandlerfintsig)
(
if(sig==SIGUSRl)
(
printf("受到SIGUSR1信号,GAMEOVER!\n");
}
)
intmain(intargc,char*argv[])
(
,intA,I;
intN=1000;
intSUM=0;
for(1=0;l<4;l++)
(
oA=(int)argv-48;
A=A*N;
=N/10;
SUM=SUM+A;
)
//printf("%dn,SUM);
PORT=SUM;
structsockaddrjnsin;
pthread_tthreadl;//发送线程
pthread_tthread2;//接受线程
printf("Socket...");
ld=socket(AF_INET,SOCK_STREAM,0);〃仓4建一个套接
〃初始化网络通信地址结构体变量
bzero(&sin,sizeof(sin));
®sin.sin_family二AF_INET;
sin.sin_port=htons(PORT);
®sin,sin_addr.s_addr=inet_addr(SERVERJP);
//发送连接请求
®printf("Connecting...\n"
connect(1d,(struetsockaddr*)&sin,sizeof(sin));
//从此处开始程序分做两个线程
〃创建发送消息的线程,调用了发送消息的函数send_message
pthread_create(&threadl,NULL,(void*)(&send_message),NULL);
charbuff[500],buffl[10];
int\en,1enl;
intkk=0;
,if((len=recv(Id,buff,l000,0))>0)〃len为读入的字节数
od{
buff[1en]='\0'
printf(”\t\t\t\t[接受消息:]%s\n\n",buff);o
,〃客户端1收到消息后作出回应
—_—_―_—_一_————一———————————_—_—————_—_—————_—_______—_—
key_tkey=ftok(argv[1],1);
,,intmsgid=msgget(keyJPC_CREAT|0666);。
,dstructmsgbufmessage;
,,message.mtype=getpid();
dstrcpy(message.mtext,buff);
e,intres=msgsnd(msgid,&message,sizeof(message.mtext),0);
if(signa1(SIGUSR1,handier)==SIG_ERR)
®®dperror("signalfail");
axit(-1);
)
,printf("向客户端2发送字符串:%s\n",message.mtext);
3printf("等待客户端2进程发送信号!pid:%d\n",message.mtype);
3sleep(30);
return0;
)
〃用户发送聊天消息
voidsend_message()
(
charname[50];〃用户
printf("pieaseinputyourname:");
。//charname[20
,scanf("%s*',name);
getchar();
,send(1d,name,str1en(name)+1,0);
owhile(1)
°{
叩rintf("»>>>>>»>>欢迎客户端进入!<VV<V<<V<<V<<\n");
6ftsingIe()
}
voidsingle()
(
®charnews[500];〃发送的消息
printf("请输入:用户消息内容:(bye退出叭n“);
。while(1)
(
ogets(news);
if(strcmp(news,"byen)==0)
o(
。printf("已退出!!!!!\n");
。»exit(0);
send(Id,news,strlen(news)+l,0);
)
)
#inc1ude<stdio.h>
#include<stdlib.h>
#inc1ude<sys/socket.h>
#include<arpa/inet.h>
include<string.h>
#include<pthread.h>
#include<sys/types.h>
include<sys/ipc.h>
#inc1ude<sys/msg.h>
#inc1ude<signaI.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#inc1ude<1imits.h>
#defineBUFESPIPE_BUF
#defineSIZE10
#defineSERVERJP"127.0.0.l“〃服务器端IP
intPORT;
intId;
voidsend_message();
voidsing1e();
structmsgbuf
(
longmtype;
charmtext[SIZE];
);
intmain(intargc,char*argv[])
(
intA,I;
intN=1000;
。intSUM=0;
for(1=0;K4;l++)
U
oA=(int)argv[1][l]-48;
,A=A*N;
o,N=N/lO;
6SUM=SUM+A;
}
//printf("%dH,SUM);
oPORT=SUM;
structsockaddr_insin;
pthread__tthread1;〃发送线程
pthread_tthread2;〃接受线程
printf("Socket...");
Hd=socket(AF_lNET,SOCK_STREAM,0);//创建一个套接字
。//初始化网络通信地址结构体变量
»bzero(&sin,sizeof(sin));
sin・sin_family=AF_INET;
sin.sin_port=htons(P0RT);
osin.sin_addr.s_addr=inet_addr(SERVER_IP);
,//发送连接请求
printf(nConnecting...\n
connect(Id,(struetsockaddr*)&sin,sizeof(sin));
//从此处开始程序分做两个线程
〃创建发送消息的线程,调用了发送消息的函数send_message
pthread_create(&threadl,NULL,(void*)(&send_message),NULL);
charbuff[500],buffl[10];
intIenJeni;
intkk=0;
3。if((Ien=recv(ld,buff,1000,0))>0)//Ien为读入的字节数
a®buff[len]='\0,;
,oprintf("\t\t\t\t[接受消息:]%s\n\n",buff)/。
01A//-———————_______——.________-
f°!!———————————————————————————————————————
。keytkey=ftok(argv[l],l);
ddintmsgid=msgget(keyjPC_CREAT|0666);
dostructmsgbufmessage;
intres=msgrcv(msgid,&message,sizeof(message.mtext),0,0);
if(res>0)
®message.mtext[res]='\0';
6Printf("从客户端1接受消息为:%s\n",message.mtext);
,)
printf("message.mtype:%d\n",message.mtype);
(kill((int)message.mtype,SIGUSRI)==0)
°{
mprintf("客户端2进程发送SIGUSR1成功!\n");
JA///-—-—--—-—--------"-_--_-_--_-_-_--_------—-—--—-—-_-_--"-_-_-_--_-_--_---------_--“-_-_--_-_--_-_--_-_-_----_-_--------,
---———_—_—_—_—_—_—_—__---
intfd2;
,mode_tmode=O_NONBLOCK;//
ifo("kkk'^mode))vOg
0{
,perror("fai1edtomkfifo");
exit(l);
°}
oif((fd2=open(”kk",O_WRONLY))<0)
3,{
perror("open");
exit(l);
}
6charcc[]="蒋浩一14级移动一班”;
。write(fd2,cc,strlen(cc));
f>close(fd2);
return0;
)
//用户发送聊天消息
voidsend_message()
(
charname[50];//用户
printf('*pleaseinputyourname
o//charname[20];
seant("%s,name);
®getchar();
dsend(ld,namezstrIen(name)+l,0);
,while(l)
{
,printf(H>>>»»»>>欢迎客户端进入!VVVVV«VvvV<<\n");
®»singIe();
}
voidsingIe()
(
charnews[500];〃发送的消息
,printf(“请输入:用户消息内容:(bye退出!)\nM);
while(l)
(
,gets(news);
•if(strcmp(news,nbye")==0)
dd{
,,printf(“已退出!!!!!\nM);
,,,exit(0);
Q}
send(ld9news,strlen(news)+1,0);
charmess[100]="蒋浩」4级移动一班“;//将发送给客户端3
send(Id,mess,str1en(mess)+l,0);
}
#include<stdio.h>
#include<stdlib.h>
#inc1ude<sys/socket.h>
#inelude<arpa/inet.h>
#include<string.h>
#include<pthread.h>
include<signa1.h>
#include<fcntl.h>
#inc1ude<sys/stat.h>
#include<sys/types.h>
#include<errno.h>
#inc1ude<unistd.h>
#include<limits.h>
#defineBUFESPIPE_BUF
#defineSERVER_IP"127.0.0.l”〃服务器端IP
intPORT;
int1d;
voidsend_message();
voidsing1e();
intmain(intargc,char*argv[])
(
intA,I;
eintN=1000;
ointSUM=O;
for(l=0;l<4;l++)
(
A=(int)argv[1][l]—48;
。A=A*N;
QN=N/10;
,SUM二SUM+A;
//printf(M%d”,SUM);
。PORT:SUM;
structsockaddrjnsin;
dpthread_tthreadl;//发送线程
epthread_11hread2;//接受线程
printf("Socket...");
,Id=socket(AFJNET,SOCK_STREAM,0);〃创建一个套接字
〃初始化网络通信地址结构体变量
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_port=htons(PORT);
sin.sin_addr.s_addr=inet_addr(SERVER_IP);
。〃发送连接请求
printf(*'Connecting...\n");
connect(1d,(structsockaddr*)&sin,sizeof(sin));
〃从此处开始程序分做两个线程
//创建发送消息的线程,调用了发送消息的函数send.message
pthread_create(&thread19NULL,(void*)(&send_message),NULL);
charbuff[50
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 冀少版八年级生物上册第三、四、五章整合练课件
- 企业商务接待规范指南
- 人力资源合规风险防范成本分析
- 北京市礼品合同
- 智能化印刷生产施工合同
- 电力系统升级施工合同范本
- 畜牧业用地租赁合同
- 社区义工活动策划与实施
- 交响乐团指挥聘任合同
- 教育信息化项目投标保证金办法
- 四川省成都市2023-2024学年高一上学期语文期中考试试卷(含答案)
- 孙中山诞辰纪念日主题班会主题班会
- 少儿美术幼儿园课件- 4-6岁 《秋梨》
- 2号表-天津市基本医疗保险住院医疗费申请支付审核单
- 简易呼吸气囊操作评分标准
- 厨房安全生产培训内容
- 苹果公司岗位职责任职要求
- PON网络组网安全问题研究
- 数字音效处理器 项目报告
- 赶工措施施工方案(完整版)
- 随机前沿分析完整版
评论
0/150
提交评论