[size=medium]
通信项目做了好长时间,今天回过头,重新温习一下学过的知识,并总结一下知识。
既然讲到通信,那么首先就要提到一个问题:
什么是通信?
我在未学习通信之前的理解:
通信就是联网,不联网何来通信,联网之后进行数据传递就行了。
对服务器,客户端都只是一个模糊的概念,只知大概,不知全貌。
最可悲的是不知道数据是如何传递的。
学习后对通信的理解:
首先解释几个名词:
服务器:在几台电脑之间建立连接之前,等待连接的机器。
客户端:主动连接其他机器的机器。
每台机器都有一个ip地址,和0~65535端口(0~1024已有其他用途,自己连接时最好不要用)
网址与服务器地址的关系:服务器地址由9~10位数字组成,网址是一个域名,
两者是映射关系
常用的几个与网络有关的dos命令
1.ping netjava.cn 查看网络是否通畅
2.telnet [服务器地址] [端口号] 连接服务器的指定端口
3.netstat -an 查看和自己的机器通信的网络
4.tracert [网址] 跟踪你的机器与连接目标地址间的路由器
通信的途径就是:(核心就是协议)
1.服务器和客户端建立连接
2.获得两者的输入流,输出流
3.制定协议
4.根据服务器与客户端间制定的协议进行数据的读,写解析
那么什么叫做协议呢?通俗的说就是两个人之间定义的一个口号,或一个约定
你们按照自己的约定可以明白对方的意思,机器之间明确自己进行的操作。
下面用代码简单实现以下发送聊天消息和文件:
制定协议:
消息:消息总长(int)+消息类型(byte)+消息内容(byte[])+目标客户账号(int)
文件:文件数据总长(int)+数据类型(byte)+目标客户账号(int)+文件名(byte[256])
+文件内容(byte[])
/**
*界面等代码就省略了,只写下服务器和客户端的传输数据的功能实现
*Client:客户端
*Server:服务器
*/
package 通信;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
// 启动主函数
public static void main(String[] args) {
Server se = new Server();
se.setServer(8732);
}
public void setServer(int port) {
try {
// 建立绑定在指定端口上的服务器对象
ServerSocket server = new ServerSocket(port);
while (true) { // 让服务器进处循环等待状态
Socket client = server.accept();
// 调用处理连接对象的方法去处理连接
calChat(client);
}
} catch (Exception ef) {
ef.printStackTrace();
}
}
// 处理客户机进入的连接对象
private void calChat(Socket client) {
try {
// 得到一个输出/输入流对象
OutputStream out = client.getOutputStream();
InputStream ins = client.getInputStream();
// 将输入流包装为DataInputStream方便读取原始类型的流
DataInputStream dins = new DataInputStream(ins);
while (true) {
// 开始读取数据:每一条消息
// 1.读消息长度
int totalLen = dins.readInt();
// 2.读取消息类型标识
byte flag = dins.readByte();
// 3.读取目标客户账号
int destNum = dins.readInt(); // 消息头解析完毕
// 根据消息的类型,读取消息体部分
if (flag == 1) {// 类型为1,是文本聊天消息,按其规则读取
// 创建对应消息体部分字节的长度的数据
byte[] data = new byte[totalLen - 4 - 1 - 4];
// 从流中读取data.length个字节放入数组中
dins.readFully(data);
String msg = new String(data);// 转成字符串
} else if (flag == 2) {// 文件数据包体解析
System.out.println("发送文件给:" + destNum);
byte[] data = new byte[256];
dins.readFully(data);// 读取256个字节做文件名字
// 解析出了文件名字,并去除末尾空格
String fileName = new String(data).trim();
// 余下的字节就是文件内容
data = new byte[totalLen - 4 - 1 - 4 - 256];// 文件字节数据总长
dins.readFully(data);// 读入文件的字节
// 保存文件到当前目录下:
FileOutputStream fous = new FileOutputStream(fileName);
fous.write(data);
fous.flush(); //将缓冲数据全部输出
fous.close(); //关闭文件输出流
} else {
client.close();
}
}
} catch (Exception ef) {
ef.printStackTrace();
}
}
}
//客户端
package 通信;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private DataOutputStream dous;// 输出流对象
//发送字符串
private void writeString(DataOutputStream out, String str,int length) {
try {
byte[] data = str.getBytes(); //将字符串转化为字符数组
out.write(data); //向服务器发送数据
while(length>data.length){
out.writeByte('\0');//补二进制0
length--;
}
} catch (Exception ef) {
ef.printStackTrace();
}
}
//发送文本消息给目标账户
private void sendTextMsg(String msg, int account) {
try {
byte[] sb = msg.getBytes();// 得到消息的字节数
//消息总长=自身长度(int)+消息类型(byte)+账号(int)+消息内容(byte[])
int totalLen = 4 + 1 + 4 + sb.length;
dous.writeInt(totalLen); // 总长
dous.writeByte(1); // 类型:1为文本消息
dous.writeInt(account);// 写入目标用户号
dous.write(sb);// 写入消息内容
dous.flush();
} catch (Exception ef) {
ef.printStackTrace();
}
}
//发送指定的文件给目标用户
private void sendFile(String fileName, int destNum) {
try {
// 根据文件名创建文件对象
File file = new File(fileName);
// 根据文件对象,构造一个输入流
InputStream ins = new FileInputStream(file);
int fileDataLen = ins.available();// 文件数据总长
int totalLen = 4 + 1 + 4 + 256 + fileDataLen; // 得到了要发送数据包的总长
dous.writeInt(totalLen);
dous.writeByte(2);// 类型是2,即文件数据包
// 写入目标用户号
dous.writeInt(destNum);
// 文件名:得到文件的短名字
String shortFileName = file.getName();
// 写入文件名
writeString(dous, shortFileName,256);
byte[] fileData = new byte[fileDataLen];
ins.read(fileData);// 读入文件数据
dous.write(fileData);// 写出到服务器的流中
dous.flush(); // 刷新流
} catch (Exception ef) {
ef.printStackTrace();
}
}
//根据制定的服务器地址和端口连接服务器
public void LinkServer(String ip, int port) {
// 创建一个到服务器端的Socket对象
try {
Socket client = new Socket(ip, port);
// 得到输入输出流对象
InputStream ins = client.getInputStream();
OutputStream ous = client.getOutputStream();
// 将输出流包装为DataOutputStream对象
dous = new DataOutputStream(ous);
int num = 0;
while (true) {
System.out.println("登录服务器成功,请选择你要发的类型(1:聊天 2:文件:");
// 让用户从命令行输入要发送的文件名字
Scanner sc = new java.util.Scanner(System.in);
int type = sc.nextInt();
if (type == 1) {// 发文本
sendTextMsg("我要发送问文本了" +num++, 8380);
}
if (type == 2) {// 发文件,注这个文件必须存在
sendFile("d:\\wjh.txt", 8380);
}
num++;
}
} catch (Exception ef) {
ef.printStackTrace();
}
}
// 主函数
public static void main(String[] args) {
Client client = new Client();
client.LinkServer("localhost", 8732);
}
}
其实除了这种发送方式还有其他方式:
你把文件(MyFile)和消息(MyMessage)用类分装,将前面发送的东西设置为属性,在属性里面定义,set和get方法
发送时,先创建输入,输出流对象ins,dous
写入对象类型标识flag(byte)
然后用对象输入流封装ObjectInputStream input=new ObjectInputStream(ins);
调用input.ReadObject();
根据flag的值用相应类的对象接收
我以前也是用这种方法
最后调用该类的get方法输出,就ok了
该方法代码实现随后见通信(2)
[/size]
分享到:
相关推荐
Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏Java SE 坦克大战小游戏...
基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java ...
本课题是应用了计算机网络通信技术和JAVA网络编程的基础知识,以JAVA为平台,利用Eclipse开发工具,并使用SQL Server 2000管理数据库数据开发出的基于Socket的网络即时通信系统。(论文+源代码+开题报告)
Java SE(Java Standard Edition)是Java开发平台的一个版本,主要针对桌面应用和服务器端开发。Java SE 14是Oracle公司发布的第14个主要版本,它包含了对Java语言特性和JVM(Java Virtual Machine)的诸多改进和新...
Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE程序 皮肤Java SE...
Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE程序 递归Java SE...
Java SE Development Kit 8u202 是Oracle公司发布的一个重要的Java开发工具包,主要用于Java Standard Edition(Java SE)的应用程序开发和运行。这个版本的JDK是Java 8的一个更新,版本号u202表示它是一个更新版本...
Java SE8 人机猜拳小游戏.zipJava SE8 人机猜拳小游戏.zip Java SE8 人机猜拳小游戏.zipJava SE8 人机猜拳小游戏.zip Java SE8 人机猜拳小游戏.zipJava SE8 人机猜拳小游戏.zip Java SE8 人机猜拳小游戏.zipJava SE8...
android java 开发can通信所用到的 candev,jar包 导入项目 可以进行can通信 canid 标准帧 扩展帧 数据 进行接收和发送
Java语言规范 基于 Java SE 8.pdf
《Java SE编程指南》是一本专注于Java Standard Edition(SE)开发的教程,尤其对初学者具有极高的指导价值。在Java SE中,我们探讨的是Java的核心特性,包括基础语法、面向对象编程、集合框架、异常处理、输入输出...
总的来说,《Java SE6 技术手册(下)》是Java开发者必备的参考书籍之一,它不仅涵盖了Java SE6的关键特性,还提供了丰富的实践案例和技巧,帮助读者提升开发效率,掌握Java平台的核心技术。无论你是初学者还是经验...
Java SE Development Kit(JDK)是Oracle公司提供的用于开发Java应用程序的核心工具集,适用于Windows平台的x64架构。在Java SE Development Kit 11.0.15.1版本中,我们看到的是一个针对64位操作系统的安装程序,这...
Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片Java SE程序 添加图片...
Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果Java SE程序 动画效果...
JAVA开发高性能IM即时通信系统源码,JAVA语言开发的轻量、高性能、单机支持几十万至百万在线用户IM,主要目标降低即时通讯门槛,快速打造低成本接入在线IM系统,通过极简洁的消息格式就可以实现多端不同协议间的消息...
Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE程序 菲波拉契数列Java SE...
培训班老师给的资料,java se部分15个小项目,很不错的,文档形式的,主要是给点提示,并且包含一部分代码,15个项目分别为:五子棋,仿windows计算器, 图片浏览器,桌面弹球,俄罗斯方块,仿windows画图,单机...
Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序 Scanner类Java SE程序...