计算机网络实验一.docx
- 文档编号:12457201
- 上传时间:2023-04-19
- 格式:DOCX
- 页数:39
- 大小:768.97KB
计算机网络实验一.docx
《计算机网络实验一.docx》由会员分享,可在线阅读,更多相关《计算机网络实验一.docx(39页珍藏版)》请在冰豆网上搜索。
计算机网络实验一
《计算机网络原理》
实验报告
项目名称计算机网络原理实验报告
专业班级软件工程1501
学号3903150104
姓名李斌
实验成绩:
批阅教师:
年月日
实验1《WindowsSocket编程》
实验学时:
2实验地点:
二综202实验日期:
一、实验目的
通过实验,使学生熟悉并掌握计算机Windows编程的基本知识,进一步加深学生对课堂所学基本内容的理解,掌握基本的Windows编程技巧,通过实验使得学生能够进行一些简单的网络程序设计。
二、实验内容
1.介绍基本的WindowsSocket编程技巧;
2.基于WindowsSocket编程,设计并实现一个简单的聊天系统,包括客户端及服务器端。
三、实验方法
参考实验指导书进行实验,若有不会的进行XX查询。
四、实验步骤
1、服务器端的搭建:
创建服务器端的socket,传入端口号:
ServerSocketserverSocket=newServerSocket(post);
在子线程监听客户端的连接:
Socketsocket=serverSocket.accept();
获取输出流,向客户端输出信息:
OutputStreamos=socket.getOutputStream();
最后关闭socket:
socket.close();
2、客户端的搭建:
创建客户端的socket,传入服务器端的ip与端口号:
SocketclientSocket=newSocket(ip,post);
建立输出流,向服务器发送消息:
getOutputStreamos=clientSocket.getOutputStream();
5、实验结果
1、开启服务器可以点击“开启服务器”按钮,若想连接服务器则输入IP地址,然后进入聊天即可:
2、开启服务器:
3、连接服务器,进入聊天室:
再连接一个客户端,这次ip地址输入localhost,因为localhost可以表示本机的ip地址:
4、开始聊天:
5、开启私聊:
六、实验结论
实验实现了socket编程,能够建立一个简陋的聊天室。
附上源代码:
服务器端:
packagechatRoom;
importjava.io.*;
import.ServerSocket;
import.Socket;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
/**
*服务端应用程序
*/
publicclassChatServer
{
privateArrayList
intpost=2020;
privateServerSocketserverSocket;
privateExecutorServicethreadPool;
privateMap
publicChatServer()
{
try
{
/*
*创建ServerSocket,并申请服务端口
*将来客户端就是通过该端口连接服务端程序的
*/
serverSocket=newServerSocket(post);
/*
*初始化Map集合,存放客户端信息
*/
allOut=newHashMap
/*
*初始化线程池,设置线程的数量
*/
threadPool=Executors.newFixedThreadPool(10);
}
catch(Exceptione)
{
e.printStackTrace();
}
}
/*
*将客户端的信息以Map形式存入集合中
*/
privatevoidaddOut(Stringkey,PrintWritervalue)
{
synchronized(this)
{
allOut.put(key,value);
}
}
/*
*将给定的输出流从共享集合中删除
*参数为客户端nickName,作为Map的key键
*/
privatesynchronizedvoidremoveOut(Stringkey)
{
allOut.remove(key);
//System.out.println("当前在线人数为:
"+allOut.size());
}
/*
*将给定的消息转发给所有客户端
*/
privatesynchronizedvoidsendMsgToAll(Stringmessage)
{
for(PrintWriterout:
allOut.values())
{
out.println(message);
//System.out.println("当前在线人数为:
"+allOut.size());
}
}
/*
*将给定的消息转发给私聊的客户端
*/
privatesynchronizedvoidsendMsgToPrivate(Stringnickname,Stringmessage)
{
PrintWriterpw=allOut.get(nickname);//将对应客户端的聊天信息取出作为私聊内容发送出去
if(pw!
=null)
{
pw.println(message);
//System.out.println("当前在线私聊人数为:
"+allOut.size());
}
}
/**
*服务端启动的方法
*/
publicvoidstart()
{
try
{
while(true)
{
Socketsocket=serverSocket.accept();
System.out.println("客户端连接成功!
");
Runnablerun=newGetClientMsgHandler(socket);
threadPool.execute(run);//通过线程池来分配线程
}
}
catch(Exceptione)
{
e.printStackTrace();
}
}
/**
*该线程体用来处理给定的某一个客户端的消息,循环接收客户端发送
*的每一个字符串,并输出到控制台
*@authorJacob
*
*/
classGetClientMsgHandlerimplementsRunnable
{
/*
*该属性是当前线程处理的具体的客户端的Socket
*@seejava.lang.Runnable#run()
*/
privateSocketsocket;
/*
*获取客户端的地址信息
*privateStringhostIP;
*/
/*
*获取客户端的昵称
*/
privateStringnickName;
/*
*创建构造方法
*/
publicGetClientMsgHandler(Socketsocket)
{
this.socket=socket;
/*
*获取远端客户的Ip地址信息
*保存客户端的IP地址字符串
*InetAddressaddress=socket.getInetAddress();
*hostIP=address.getHostAddress();
*/
}
/*
*创建内部类来获取昵称
*/
privateStringgetNickName()throwsException
{
try
{
//服务端的输入流读取客户端发送来的昵称输出流
InputStreamiin=socket.getInputStream();
InputStreamReaderisr=
newInputStreamReader(iin,"UTF-8");
BufferedReaderbReader=newBufferedReader(isr);
//服务端将昵称验证结果通过自身的输出流发送给客户端
OutputStreamout=socket.getOutputStream();
OutputStreamWriteriosw=
newOutputStreamWriter(out,"UTF-8");
PrintWriteripw=newPrintWriter(iosw,true);
//读取客户端发来的昵称
StringnameString=bReader.readLine();
while(true)
{
if(nameString!
=null&&nameString.contains("~")){
Stringusername=nameString.substring(nameString.indexOf("~")+1,nameString.length());
if(!
allOut.containsKey(username)){
ipw.println("OK");
returnusername;
}else{
ipw.println("Exist");
}
}
nameString=bReader.readLine();
}
}
catch(Exceptione)
{
e.printStackTrace();
}
returnnull;
}
@Override
publicvoidrun()
{
PrintWriterpw=null;
try
{
/*
*通过客户端的Socket获取客户端的输出流
*用来将消息发送给客户端
*/
OutputStreamos=socket.getOutputStream();
OutputStreamWriterosw=newOutputStreamWriter(os,"UTF-8");
pw=newPrintWriter(osw,true);
/*
*将客户昵称和其所说的话作为元素存入共享集合HashMap中
*/
nickName=getNickName();
addOut(nickName,pw);
Thread.sleep(100);
/*
*服务端通知所有客户端,某用户登录
*/
sendMsgToAll("[系统通知]:
欢迎**"+nickName+"**登陆聊天室!
");
names.add(nickName);
//System.out.println(names.toString());
sendMsgToAll("names:
"+names.toString());
/*
*通过客户端的Socket获取输入流
*读取客户端发送来的信息
*/
InputStreamis=socket.getInputStream();
InputStreamReaderisr=newInputStreamReader(is,"UTF-8");
BufferedReaderbr=newBufferedReader(isr);
StringmsgString=null;
while((msgString=br.readLine())!
=null)
{
//验证是否是私聊
if(msgString.startsWith("@"))
{
/*
*私聊格式:
@昵称:
内容
*/
intindex=msgString.indexOf(":
");
if(index>=0)
{
//获取昵称
Stringname=msgString.substring(1,index);
Stringinfo=msgString.substring(index+1,msgString.length());
info=nickName+"对你说:
"+info;
//将私聊信息发送出去
sendMsgToPrivate(name,info);
//服务端不在广播私聊的信息
continue;
}
}
/*
*遍历所有输出流,将该客户端发送的信息转发给所有客户端
*/
//System.out.println(nickName+"说:
"+msgString);
sendMsgToAll(nickName+"说:
"+msgString);
}
}
catch(Exceptione)
{
}
finally
{
removeOut(nickName);
/*
*通知所有客户端,某某客户已经下线
*/
sendMsgToAll("[系统通知]:
"+nickName+"已经下线了。
");
names.remove(nickName);
sendMsgToAll("names:
"+names.toString());
/*
*关闭socket,则通过Socket获取的输入输出流也一同关闭了
*/
if(socket!
=null)
{
try
{
socket.close();
}
catch(IOExceptione)
{
e.printStackTrace();
}
}
}
}
}
/*publicstaticvoidmain(String[]args)
{
//ChatServerserver=newChatServer();
//server.start();
}*/
}
客户端:
packagechatRoom;
importjavafx.application.Application;
importjavafx.beans.value.ObservableValue;
importjavafx.collections.FXCollections;
importjavafx.collections.ObservableList;
importjavafx.event.EventHandler;
importjavafx.geometry.HPos;
importjavafx.geometry.Insets;
importjavafx.geometry.Pos;
importjavafx.scene.Group;
importjavafx.scene.Scene;
importjavafx.scene.control.*;
importjavafx.scene.control.Alert.AlertType;
importjavafx.scene.input.KeyCode;
importjavafx.scene.input.KeyEvent;
importjavafx.scene.layout.*;
importjavafx.scene.paint.Color;
importjavafx.scene.text.Font;
importjavafx.scene.text.Text;
importjavafx.stage.Stage;
importjavax.swing.*;
importjava.io.*;
import.Socket;
importjava.util.ArrayList;
importjava.util.Scanner;
publicclassChatRoomextendsApplication{
booleanisWrong=false;
booleancanChat=false;
booleanisChating=false;
Stringip="127.0.0.1";
intpost=2020;
TextFieldsendField;
TextAreamsgArea;
ListView
OutputStreamos;
OutputStreamWriterosw;
PrintWriterpw;
Stringname;
privateChatServerchatServer;
publicvoidstart(StageprimaryStage)throwsException{
GridPanepane=newGridPane();
pane.setAlignment(Pos.CENTER_LEFT);
pane.setPadding(newInsets(20,20,20,40));
pane.setHgap(5.5);
pane.setVgap(5.5);
Labellabel_ip=newLabel("主机IP地址:
");
pane.add(label_ip,0,0);
TextFieldtf_id=newTextField();
pane.add(tf_id,1,0);
Labellabel_name=newLabel("聊天姓名:
");
pane.add(label_name,0,1);
Buttonbtn_startServer=newButton("开启服务器");
pane.add(btn_startServer,0,2);
TextFieldtf_chatName=newTextField();
pane.add(tf_chatName,1,1);
Buttonbtn_login=newButton("进入聊天");
pane.add(btn_login,1,2);
GridPane.setHalignment(btn_login,HPos.LEFT);
Panepane1=newPane();
Scenescene=newScene(pane1,430,300);
Stagestage=newStage();
stage.setScene(scene);
stage.setTitle("Chat");
stage.setResizable(false);
stage.show();
btn_login.setPrefSize(200,4);
btn_login.setStyle("-fx-text-fill:
white;-fx-background-color:
#1C86EE;-fx-background-radius:
5");
btn_login.setFont(newFont("bold",13));
btn_startServer.setStyle("-fx-text-fill:
white;-fx-background-color:
#1C86EE;-fx-background-radius:
5");
btn_startServer.setFont(newFont("bold",13));
label_ip.setFont(newFont("bold",15));
label_name.setFont(newFont("bold",15));
tf_id.setPrefSize(200,30);
tf_id.setStyle("-fx-background-radius:
0");
tf_chatName.setPrefSize(200,30);
tf_chatName.setStyle("-fx-background-radius:
0");
pane1.setStyle("-fx-background-image:
url('/image/background1.jpg');"
+"-fx-background-repeat:
no-repeat;"
+"-fx-background-position:
center;"
+"-fx-background-size:
stretch");
pane1.getChildren().add(pane);
pane.setLayoutX(0);
pane.setLayoutY(150);
pane.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 实验