网络编程课程
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
---java聊天室
《Windows网络编程》课程设计
《Windows网络编程技术》课程设计报告
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
目:
院 系:
年 月 日 专业班级: 学 号: 学生姓名: 指导教师:
《Windows网络编程》课程设计
1.引言
1) 本课题的来源 随着网络普及和上网人数的大增,在国内各大门户网站都架设了大型聊天室。如:新浪聊天室、中华网社区聊天室、搜狐等都成为网民们的热门聊天室。以新浪聊天室为例看,聊天室呈现积聚人气作用,并开设不同主题的聊天室以使网民们具有针对性的使用聊天室。
本小组计划设计一个实现基于Java语言的聊天室的Windows网络编程,启动服务
器后,客户端运行,向服务器端发出请求,连接成功后,会弹出一个聊天室的界面,该界面有私聊(可加入生动的表情描述)、群聊、发送文件等功能,客户可以根据自己的需要选择不同的功能。本人在此小组中的具体任务是实现文件的接收功能,启动服务器监听后,接收客户端发来请求,安排线程接收对方发来的文件(例如文档、照片、音乐、电影等)并存入指定的文件夹中。
2)本系统涉及的
知识点
高中化学知识点免费下载体育概论知识点下载名人传知识点免费下载线性代数知识点汇总下载高中化学知识点免费下载
1、套接字Socket的建立、连接、关闭,客户端和服务器端的输入/输出流的连接。
2、Java中的多线程及线程的常用方法、Runnable接口。
3、基于SWING的图形用户界面设计:布局设计、文本组件、按钮与标签组件、列表组件等。
4、InetAddress类。
5、输入/输出流:文件、文件字节流、文件字符流、缓冲流、数据流。
3)功能要求
(1)在服务器端和客户端分别创建一个套接字对象,通过输入输出流连接在一起。套接字调用close()方法关闭双方的套接字连接。
《Windows网络编程》课程设计
(2)使用多线程处理套接字连接,把服务器端或客户端读取的数据放在一个单独的线程中去进行,防止服务器端或客户端读取数据可能引起的堵塞。服务器端
收到一个客户的套接字后,应该启动一个专门为该客户服务的线程。
(3)成功连接后,在图形界面中用户可以根据自己的需要进行不同的操作,如:群聊天、和某一个用户单独聊天(可加入生动的表情描述)、发送文件等。在界面中会显示用户的聊天
记录
混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载
。
4)开发环境的选择
在进行开发之前,首先决定的第一个问题就是,该使用什么开发环境来编写该系统?以目前常用的开发语言来讲有C/C++、.NET技术,JAVA、 Visual Basic几种。还有Eclipse,、Borland JBuilder等,这些并不是程序语言,而是程序语言在建构程序时的“集成开发工具”,不过它们在开发设计的过程中也占有相当重要的角色,因为选用正确的集成开发工具,可以加速程序设计的进行、测试与排错,因而对整体进度具有决定性的影响。
基于以下几点,选择JAVA语言开发技术。
1、就执行平台而言,必须考虑的问题之一是用户可能使用的操作系统。用户可能使用的是Windows Linux。JAVA语言具有平台无关性,可以不需要任何修改就可以运行在支持JAVA的任何计算机上。
2、JAVA的Swing 组件开发技术可以开发丰富的图形界面,并且Swing API类提供了丰富的外部接口和方法,可以方便实现系统功能。
3、就项目开发而言,纯粹的面向对象,加上数量巨大的类所提供的方法(函数)库的支持,使得利用Java开发各种应用程序,可以说是易如反掌。此外,在程序除错、修改、升级和增加新功能等方面,因其面向对象的特性,使得这些维护也变得非常容易。
4、Java支持内在的多线程运行,提供分布式的并发机制,运行效率高。
5、异常处理,为了使Java程式更稳定、更安全,Java引入了异常处理机制。能够在程序中产生异常情况的地方,执行相对应的处理,不至于因突发或意外的错误造成执行中断或是死机。通过这种异常处理,不仅能够清晰地掌握整个程序执行的流程,也使得程序的设计更为严谨。
6、高性能,Java可以在运行时直接将目标代码翻译成机器指令。Sun用直
《Windows网络编程》课程设计
接解释器一秒钟 如果你需要在两台机器之间进行通讯而不使用高级机制像ORBs(以及CORBA, RMI, IIOP等等),socket比较适合你。Socket的底层机制则相当棘手。幸运的是,java平台给我们一些虽然简单但是相当强大的高层抽象以至于我们创建和使用socket更加容易一些。
一般而言,java socket有下面两种类型:
•TCP socket(由Socket类实现,下面的章节我们将对其讨论)
•UDP socket(由DatagramSocket类实现)
TCP和UDP扮演同样的角色,但是实现是不同的。两者都接收传输协议数据包并
《Windows网络编程》课程设计
把它们传递到表示层。TCP把信息分解成数据包(datagrams)并在接收端重新组装起来。它还对丢失的数据包进行重新传输的请求。TCP减少了上层的担忧。UDP没有组装和重传请求的功能。它只是传输数据包。更高层的层必须确保信息的完
整性以及组合顺序的正确性。
2、功能设计
1、Socket socket = new Socket(String host,int port);客户端创建Socket对象,host
,port是一个端口号,该对象用于连接服务器。 是服务器端的IP地址
2、BufferedReader br=new BufferedReader
(new InputStreamReader(socket.getInputStream())); 创建一个使用默认大小输入缓冲区的缓冲字符输入流。该输入流的指向是一个Reader流,Reader流将数据读入缓冲区,BufferedReader再从缓冲区中读取数据。InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符。getInputStream()获取字节输入流。
3、PrintStream ps = new PrintStream(socket.getOutputStream());创建新的打印流,PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的服务器端文件的长度。
8、FileInputStream fis = new FileInputStream(file); 创建FileInputStream从文件中读取数据,OutputStream out = socket.getOutputStream();输出字节流,输出流接收输出字节并将这些字节写出到Socket的输出流。
9、fis.skip(finishLen); 从输入流中跳过并丢弃finishLen个字节的数据,即跳过服务端已完成的大小。
10、len = fis.read(byte[] buffer)); 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
11、out.write(byte[] b,int off,int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
《Windows网络编程》课程设计
3、聊天室界面
4、本人负责的部分
本人主要服务器端设计,为聊天室提供信息处理服务。其主要完成的功能是监听客户端的连接,聊天内容的群发和单个转发,
通知
关于发布提成方案的通知关于xx通知关于成立公司筹建组的通知关于红头文件的使用公开通知关于计发全勤奖的通知
聊天室的客户哪些人刚上线等等。
《Windows网络编程》课程设计
5、全部程序清单:
服务器端:
package chat;
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer{
}
class ServerThread implements Runnable{
private Vector threads;
private Socket socket = null;
private DataInputStream in = null; public static void main(String[] args)throws Exception{ ServerSocket svSocket =null; } Vector threads = new Vector(); try { svSocket = new ServerSocket(5555); System.out.println ("listening..."); }catch (Exception ex) { System.out.println ("Server create ServerSocket failed!"); } return; try{ int nid = 0; while(true){ } Socket socket = svSocket.accept(); System.out.println ("accept a client"); ServerThread st = new ServerThread(socket,threads); st.setID(nid++); threads.add(st); new Thread(st).start(); for(int i=0;i < threads.size();i++){ } ServerThread temp = (ServerThread)threads.elementAt(i); System.out.println ("Listen again..."); }catch(Exception ex){ System.out.println ("server is down"); }
《Windows网络编程》课程设计
private DataOutputStream out = null; private int nid; public ServerThread(Socket socket,Vector threads){ this.socket = socket; this.threads = threads; } try { } } in = new DataInputStream(socket.getInputStream()); out = new DataOutputStream(socket.getOutputStream()); catch (Exception ex) { public void run(){ System.out.println ("Thread is running"); try{ while(true){
String receive = in.readUTF(); if(receive == null) return; //下线通知
if(receive.contains("黯然下线了")){ for(int i=0;i <
threads.size();i++){ ServerThread st = (ServerThread)threads.elementAt(i); st.write("***"+receive+"***"); } } //上线通知 else
if(receive.contains("上线了")){ for(int i=0;i <
threads.size();i++){ ServerThread st = (ServerThread)threads.elementAt(i); st.write("<"+getID()+">: "+receive); } } //作为服务
器监听中 else if(receive.contains("监听中")){ for(int i=0;i <
threads.size();i++){ ServerThread st = (ServerThread)threads.elementAt(i); st.write("***"+receive+"*** "); } } //发送消息 else
if(receive.contains("说")){ //发送广播消息
if(receive.contains("大家")){ for(int i=0;i < threads.size();i++){
《Windows网络编程》课程设计
} } ServerThread st = (ServerThread)threads.elementAt(i); st.write("<"+getID()+">: "+receive); } } //发送指定
消息 else{ } int temp=receive.indexOf("<"); int temp1=receive.indexOf(">"); //获得接收者ID号 String
tempS=receive.substring(temp+1,temp1); int i=Integer.parseInt(tempS); //指定接收
者输出 ServerThread st = (ServerThread)threads.elementAt(i); st.write("<"+getID()+">: "+receive); //发送者自己也输
出 st = (ServerThread)threads.elementAt(getID());
st.write("<"+getID()+">: "+receive); else{ ServerThread st = (ServerThread)threads.elementAt(getID()); st.write("***"+receive+"***"); } } }catch(Exception ex){ threads.removeElement(this); ex.printStackTrace(); } try{ socket.close(); }catch(Exception ex){ ex.printStackTrace(); } public void write(String msg){ synchronized(out){ }
try{ out.writeUTF(msg); }catch(Exception ex){ } } public int getID(){ return this.nid;
《Windows网络编程》课程设计
} } public void setID(int nid){ this.nid = nid; }
服务器端的文件传送:
package chat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
public class filesendServer{
public void filereceive() throws Exception{
//1.创建ServerSocket, 在循环中接收客户端请求, 每接收到一个请求就开启新
线程处理
} } ServerSocket serverSocket = new ServerSocket(1234);
!"); JOptionPane.showMessageDialog(null,"服务已启动,绑定1234端口
while(true){ Socket socket = serverSocket.accept(); new fileServerThread(socket).start(); }
class fileServerThread extends Thread{
Socket socket;
public fileServerThread(Socket socket) { } this.socket = socket; public void
run() { FileOutputStream fos = null; try { //3.获取输入输出流
BufferedReader br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
《Windows网络编程》课程设计
PrintStream ps = new PrintStream(socket.getOutputStream());
//7.接收文件, 查找是否存在. 如果存在, 给写一个消息给客户端, 服务端线程
结束. 如果不存在, 写消息给客户端, 准备开始上传.
String fileName = br.readLine(); long fileLen = Long.parseLong(br.readLine());
File dir = new File("upload"); dir.mkdir(); File file = new File(dir,fileName); if(file.exists() && file.length() == fileLen){ // 文件已
存在, length()即为文件大 ps.println("已存在"); return; 小, 文件不存
在length()为0
}
else{
ps.println(file.length()); // 文件已存在, length()即为文件大小, 文件不存在
length()为0
} //10.从Socket的输入流中读取数据, 创建FileOutputStream写出到文件中
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new
System.out.println(time + " "+ (file.exists() ? " 开始断点续传:
" : " 开始上传文
long start = System.currentTimeMillis();
InputStream in = socket.getInputStream();
fos = new FileOutputStream(file, true); // 文件存在就追加, 文件不存在则创建
Date()); 件: ") + file.getName());
byte[] buffer = new byte[1024];
int len;
while((len = in.read(buffer)) != -1){ //这个地方会堵塞,如果客服端没有关闭
socket.服务器端读不到流末尾(-1)
fos.write(buffer, 0, len); if(file.length() == fileLen) // 文件大小等于客户端文件大
break; } fos.close(); long end = System.currentTimeMillis(); 小时, 代表上传完毕
time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); System.out.println(time + " " + " 上传文件结束: " +
file.getName() + ", 耗时: " + (end - start) + "毫秒");
ps.println("上传成功");
socket.close(); if(fos != null) try { fos.close(); } catch (IOException e) {
《Windows网络编程》课程设计
} } } } catch (IOException e1) { } e1.printStackTrace();
客户端的界面设计:
package chat;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.*;
public class Client
{
public static void main(String args[])
{
new ChatClient();
}
}
class ChatClient extends Frame implements ActionListener, Runnable{
private static final long serialVersionUID = -4149839042245330513L;
public Button listen,connection,sendtoall,sendtoone,exit,filesend;
public JComboBox emote;
public TextField inputName,inputContent; public TextArea chatResult; public Socket socket=null; public DataInputStream in=null; public DataOutputStream out=null; public Thread thread; ChatClient() { socket=new Socket(); Box box1=Box.createHorizontalBox(); listen=new Button("作为服务器监听
"); connection=new Button("连接服务器"); filesend=new
Button("发送文件"); exit=new Button("退出");
sendtoall=new Button("群聊"); sendtoone=new Button("私聊
"); listen.setEnabled(false); filesend.setEnabled(false);
sendtoall.setEnabled(false);
《Windows网络编程》课程设计
sendtoone.setEnabled(false); inputName=new TextField(6);
inputName.setBackground(new Color(162,231,250)); inputContent=new TextField(22); inputContent.setBackground(new Color(162,231,250)); chatResult= new TextArea("", 17,20,TextArea.SCROLLBARS_VERTICAL_ONLY); chatResult.setBackground(new Color(162,231,250)); JLabel jlname=new JLabel("输入昵称"); box1.add(jlname); box1.add(inputName); box1.add(listen); box1.add(connection); box1.add(filesend); box1.add(exit); Box box2=Box.createHorizontalBox(); emote = new JComboBox(); emote.setModel(new DefaultComboBoxModel(new String[] { "表情", "微笑",
"甜笑", "惊喜", "嘻嘻", "扮酷",
"嘿嘿", "傻笑", "好奇", "媚眼",
"鬼脸", "陶醉", "害羞", "生气",
"嚷嚷", "发怒", "伤心", "高明",
"菜鸟", "问号", "狂笑", "大哭",
"示爱", "呻吟", "想想" }));
emote.setEnabled(false); JLabel jlintput = new JLabel("输入聊天内容");
box2.add(jlintput); box2.add(inputContent); box2.add(emote); box2.add(sendtoall); box2.add(sendtoone);
listen.addActionListener(this);
connection.addActionListener(this);
filesend.addActionListener(this);
exit.addActionListener(this); sendtoall.addActionListener(this); sendtoone.addActionListener(this); Box box3=Box.createHorizontalBox(); box3.add(chatResult); thread=new Thread(this); Box box0=Box.createVerticalBox(); box0.add(Box.createVerticalStrut(10)); box0.add(box1);
box0.add(Box.createVerticalStrut(10)); box0.add(box3);
box0.add(Box.createVerticalStrut(10)); box0.add(box2);
box0.add(Box.createVerticalStrut(10));
《Windows网络编程》课程设计
add(box0); setBounds(10,30,500,400); setBackground(new Color(80,212,248)); setVisible(true); validate(); addWindowListener(new
WindowAdapter(){ public void windowClosing(WindowEvent e){ } System.exit(0); try { socket.close(); } catch (IOException e1) { e1.printStackTrace(); }
});
}
public void actionPerformed(ActionEvent e) { ActionProcess actionProcess=new ActionProcess(this); try { actionProcess.action(e); } catch (Exception e1) { e1.printStackTrace(); } } public void run() { String s=null; while(true) { try { } s=in.readUTF(); chatResult.append("\n"+s); catch(IOException e) { chatResult.setText("与服务器断开连接"); } try { }
catch(Exception ep){} break; socket.close();
《Windows网络编程》课程设
计
}
}
}
客户端的界面事件处理:
package chat;
import java.awt.event.ActionEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import javax.swing.JOptionPane;
public class ActionProcess implements Runnable {
private ChatClient client;
String name=""; String sendtoname="";
String sendtoID;
String filename="";
String filepath="";
public ActionProcess(ChatClient client) { this.client=client; } public void action(ActionEvent e)throws Exception{ if(e.getSource()==client.connection) { try { if(client.socket.isConnected()){} else { String addr=JOptionPane.showInputDialog("请输入服务器IP:"); InetAddress
address=InetAddress.getByName(addr);
socketAddress=new InetSocketAddress
InetSocketAddress(address,5555);
client.socket.connect(socketAddress); client.in=new
DataInputStream(client.socket.getInputStream()); client.out=new DataOutputStream(client.socket.getOutputStream());
name=client.inputName.getText(); client.out.writeUTF("姓名为
"+name+"的朋友风尘仆仆地上线了...");
client.listen.setEnabled(true); client.filesend.setEnabled(true);
client.sendtoall.setEnabled(true); client.sendtoone.setEnabled(true); client.emote.setEnabled(true);
《Windows网络编程》课程设计
} } if(!(client.thread.isAlive())) client.thread=new Thread(this); client.thread.start(); } catch(IOException ee){} if(e.getSource()==client.listen) { }
if(e.getSource()==client.filesend){ if(client.socket.isConnected()) try { filesendClient filesendclient=new filesendClient(); filesendclient.filesend(); client.out.writeUTF("成功发送文件~"); }catch (Exception ee){} try { } name=client.inputName.getText(); client.out.writeUTF("姓名为
"+name+"的朋友正在监听中..."); filesendServer
filesendserver=new filesendServer(); filesendserver.filereceive(); catch (Exception
ee) { ee.printStackTrace(); } } if(e.getSource()==client.exit) { if(client.socket.isConnected()) } String
em=client.emote.getSelectedItem().toString(); if (em.equals("表情"))
{ em = ""; try { name=client.inputName.getText(); client.out.writeUTF("姓名为"+name+"的朋友黯然下线
了..."); client.out.flush(); } client.out.close(); client.socket.close(); e1.printStackTrace(); } catch (IOException e1) { System.exit(0);
《Windows网络编程》课程设计
} else { em += "着"; } if(e.getSource()==client.sendtoall) { if(client.socket.isConnected()){
name=client.inputName.getText();
String s=client.inputContent.getText();
if(s!=null)
{
try
{
client.out.writeUTF(name+em+"对大家说:"+s);
client.out.flush();
client.inputContent.setText("");
}
catch(IOException e1){}
}
}
}
if(e.getSource()==client.sendtoone)
{
if(client.socket.isConnected()){
sendtoID=JOptionPane.showInputDialog("请输入对方ID:");
sendtoname=JOptionPane.showInputDialog("请输入对方姓名:");
String s=client.inputContent.getText();
name=client.inputName.getText();
if(s!=null)
{
try
{
client.out.writeUTF(name+"悄悄地
"+em+"<"+sendtoID+">"+sendtoname+"
说:"+s);
client.out.flush();
client.inputContent.setText("");
}
catch(IOException e1){}
}
}
}
}
public void run()
{
String s=null; 对
《Windows网络编程》课程设计
} while(true) { } try { s=client.in.readUTF(); }
catch(IOException e) { client.chatResult.setText("与服务器断开连接"); } try { } client.socket.close(); client.chatResult.append("\n"+s); catch(Exception ep){} break;
}
客户端的文件接收:
package chat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import javax.swing.JOptionPane;
public class filesendClient {
public void filesend() throws Exception{
//1.创建Socket, 指定服务端IP地址和端口号, 连接服务器
String sendtoIP=JOptionPane.showInputDialog("请输入对方IP:"); Socket socket = new Socket(sendtoIP, 1234); //2.获取输入输出流 BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream()); //3.提示用户输入一个
路径,判断是否存在是否是文件, 如果输入非法给予提示, 重新输入 File file = getFile(); //4.将文件名和大小发送到服务端
《Windows网络编程》课程设计
} ps.println(file.getName()); ps.println(file.length()); //5.接收服务器发送回来的是
否存在的结果. 如果文件已存在, 打印提示, 客户端退出. 如果不存在, 准备开
始上传. String msg = br.readLine(); if("已存在".equals(msg)){ } JOptionPane.showMessageDialog(null,"文件已存在,请不要重复上传!"); return; long finishLen = Long.parseLong(msg); // 服务器端文件的长度 //6.创建
FileInputStream从文件中读取数据, 写出到Socket的输出流 FileInputStream fis = new FileInputStream(file); OutputStream out = socket.getOutputStream(); byte[]
buffer = new byte[1024]; int len; fis.skip(finishLen); // 跳过服务端已完成的大小
while((len = fis.read(buffer)) != -1) out.write(buffer, 0, len); fis.close();
socket.close(); public File getFile() throws Exception{ //得到文件的方法 File file=null; boolean flag=false; while(flag==false){ String
filepath=JOptionPane.showInputDialog("请输入要上传的路径:"); file = new File(filepath);
if(!file.exists()){ JOptionPane.showMessageDialog(null,"您输入的路径不存在,
请重新输入~"); } flag=false; else if(file.isDirectory()){ JOptionPane.showMessageDialog(null,"占不支持文
件夹上传!请输入一个
flag=false; 文件路径~");
}
} } } else flag=true; return file;