网络编程的三要素:

  1. ip地址:唯一标识网络上的每一台计算机
  2. 端口号:计算机中应用的标号(代表一个应用程序),0-1024系统使用或者保留端口,有效端口0-65535(short)
  3. 通信协议:通信的规则 TCP UDP

UDP:相当于发短信,不需要建立连接,数据包的大小限制在64k内,效率高,不安全,容易丢包

TCP:相当于打电话,需要建立连接,效率相对较低,数据传输安全,三次握手完成。


下面使用TCP进行网络通信: 
服务端:

 public static void main(String[] args) throws Exception {
//创建服务端的对象
ServerSocket ss = new ServerSocket(8000);
//等待客户端的接入
Socket client = ss.accept();
//从输入流中得到数据
InputStream is = client.getInputStream();
byte[] by = new byte[1024];
int len = is.read(by);
String str = new String(by,0,len);
System.out.println(str);
//关闭
client.shutdownInput();
is.close();
client.close(); }

客户端:

 public static void main(String[] args) throws Exception {
//创建客户端套接字对象,给定ip地址
Socket client = new Socket("192.168.6.166",8000);
//获取客户端的输出流
OutputStream os = client.getOutputStream();
//向输出流中写入数据
os.write("在?".getBytes());
os.flush();
//切断输出流
client.shutdownOutput();
//关闭流对象,关闭套接字
is.close();
os.close();
client.close(); }

通过上面的代码能够实现基本的发送信息,和接收信息。不过只能客户端发送信息,服务器被动接收信息,下面来实现客户端和服务器互相发送信息:

服务器端:

 public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8000);
Scanner sc = new Scanner(System.in);
System.out.println("服务器启动!");
Socket s = ss.accept();
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
boolean bool = true;
while(bool){
//服务器接收信息
byte[] bt = new byte[1024];
int length = is.read(bt);
System.out.println("\t\t\t"+new String(bt,0,length)+":客户端");
//服务器发送信息
System.out.println("服务器:");
os.write(sc.next().getBytes());
os.flush();
}
s.shutdownInput();
is.close();
os.close();
s.close();
ss.close(); }

客户端:

 public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("客户端启动");
Socket client = new Socket("127.0.0.1",8000);
Scanner sc = new Scanner(System.in);
boolean bool = true;
OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();
while(bool){
//客户端发送信息
System.out.println("客户端:");
String str = sc.next();
os.write(str.getBytes());
os.flush();
//客户端接收信息
byte[] by = new byte[1024];
int index = is.read(by);
System.out.println("\t\t\t"+new String(by,0,index)+":服务器");
}
client.shutdownOutput();
os.close();
is.close();
sc.close();
client.close();
}

使用上面的方式进行通信,实现结果: 
客户端:

服务器: 


这样实现了两端相互通信的要求,如果一方连续发送两条信息的时候,这个程序就会开始出现问题。于是使用线程解决这个问题,具体如下:

客户端:

 public class servletSockettest {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8888);
System.out.println("服务器启动!");
final Socket s = ss.accept();
boolean b = true;
InputStream is = s.getInputStream();
//服务器把输入放入线程里面执行,不会影响主线程的接收信息功能
Thread t = new Thread(){
OutputStream os = s.getOutputStream();
Scanner sc = new Scanner(System.in);
@Override
public void run() {
// TODO Auto-generated method stub
boolean b = true;
while(b){
try {
System.out.print("服务器输入:");
os.write(sc.next().getBytes());
os.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
while(b){
byte[] bt = new byte[1024];
int length = is.read(bt);
String str = new String(bt,0,length);
System.out.println("\t\t\t"+str+":客户端");
} is.close();
s.shutdownInput();
s.close();
ss.close(); }
}

客户端:

 public class Sockettest {
public static void main(String[] args) throws UnknownHostException, IOException {
final Socket client = new Socket("192.168.6.166",8888);
Scanner sc = new Scanner(System.in);
System.out.println("客户端启动");
OutputStream os = client.getOutputStream();
//新建一个线程用来接收信息,不影响主线程的输入发送信息。
Thread t = new Thread(){
InputStream is = client.getInputStream();
@Override
public void run() {
// TODO Auto-generated method stub
boolean b = true;
while(b){
try {
byte[] bt = new byte[1024];
int length = is.read(bt);
String str = new String(bt,0,length);
System.out.println("\t\t\t"+str+":服务器");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
t.start();
boolean b = true;
while(b){
System.out.print("客户端输入:");
os.write(sc.next().getBytes());
os.flush();
}
os.close();
client.shutdownOutput();
client.close();
}
}

运行结果: 
客户端 
 
服务器: 

这样就可以实现基本上的通信了。如果有兴趣,可以结合JFrame窗体,实现多个窗口相互聊天,不再使界面这么难看。

 
 

java网络编程实现两端聊天的更多相关文章

  1. Java网络编程(UDP协议-聊天程序)

    接收端: package WebProgramingDemo; import java.net.DatagramPacket; import java.net.DatagramSocket; publ ...

  2. Java 网络编程---分布式文件协同编辑器设计与实现

    目录: 第一部分:Java网络编程知识 (一)简单的Http请求 一般浏览网页时,使用的时Ip地址,而IP(Internet Protocol,互联网协议)目前主要是IPv4和IPv6. IP地址是一 ...

  3. Java网络编程(一)

    Java网络编程: 1.1: 网络编程:对于我这个“研究不深”的网络菜鸟来说,我觉得网络编程就是实现计算机与计算机之间通信的编程.写些能够实现计算机与计算机之间的通信就行了(目前来说). 1.2:一台 ...

  4. JAVA 网络编程 - 实现 群聊 程序

    在实现 这个 程序之前, 我们 需要 了解 一些 关于 Java 网络 编程 的 知识. 基本 的 网络知识: 网络模型 OSI (Open System Interconnection 开放系统互连 ...

  5. java网络编程socket解析

    转载:http://www.blogjava.net/landon/archive/2013/07/02/401137.html Java网络编程精解笔记2:Socket详解 Socket用法详解 在 ...

  6. [未完成]关于Java网络编程总结

    网络的七层结构: 第一层:物理层,网线. 第二层: 数据链路层,交换机.交换机有IP地址.这一层的数据叫做帧 第三层:网络层,数据包方向的定义,路由器.现在也有具有路由功能的交换机.主要将从下层接收到 ...

  7. 网络编程TCP协议-聊天室

    网络编程TCP协议-聊天室(客户端与服务端的交互); <span style="font-size:18px;">1.客户端发数据到服务端.</span> ...

  8. Java网络编程技术2

    3. UDP数据报通信 UDP通信中,需要建立一个DatagramSocket,与Socket不同,它不存在“连接”的概念,取而代之的是一个数据报包——DatagramPacket.这个数据报包必须知 ...

  9. Java网络编程技术1

    1. Java网络编程常用API 1.1 InetAddress类使用示例 1.1.1根据域名查找IP地址 获取用户通过命令行方式指定的域名,然后通过InetAddress对象来获取该域名对应的IP地 ...

随机推荐

  1. [leetcode-496-Next Greater Element I]

    You are given two arrays (without duplicates) nums1 and nums2 where nums1's elements are subset of n ...

  2. ReactiveCocoa源码解析(四) Signal中的静态属性静态方法以及面向协议扩展

    上篇博客我们聊了Signal的几种状态.Signal与Observer的关联方式以及Signal是如何向关联的Observer发送事件的.本篇博客继续上篇博客的内容,来聊一下Signal类中静态的ne ...

  3. 一个简单的python选课系统

    下面介绍一下自己写的python程序,主要是的知识点为sys.os.json.pickle的模块应用,python程序包的的使用,以及关于类的使用. 下面是我的程序目录: bin是存放一些执行文件co ...

  4. js加强版图片轮播

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. tomcat 修改为自己项目界面

    修改Tomcat欢迎界面为自己项目界面 Posted on 2011-04-16 13:10 IceWee 阅读(1062) 评论(0)  编辑  收藏 所属分类: Tomcat  由于项目要发布到互 ...

  6. 算法起步之kmp算法

    [作者Idlear  博客:http://blog.csdn.net/idlear/article/details/19555905]            这估计是算法连载文章的最后几篇了,马上就要 ...

  7. c++ 命名空间 以及 作用域 函数参数 面向对象实验报告

    面向对象的分析与设计  实验报告一 一.变量的储存类别 auto static register extern auto变量   函数中的局部变量,如不专门声明为static存储类别,都是动态地分配存 ...

  8. Oracle两张表关联批量更新其中一张表的数据

    Oracle两张表关联批量更新其中一张表的数据 方法一(推荐): UPDATE 表2 SET 表2.C = (SELECT B FROM 表1 WHERE 表1.A = 表2.A) WHERE EXI ...

  9. 架构之路 之 Nginx实现负载均衡

    [前言] 在大型网站中,负载均衡是有想当必要的.尤其是在同一时间访问量比较大的大型网站,例如网上商城,新闻等CMS系统,为了减轻单个服务器的处理压力,我们引进了负载均衡这一个概念,将一个服务器的压力分 ...

  10. C# Web.config配置

    使用 <!--M002 バッチを起動のPath配置--> <add key="BM0002_START_PATH" value="D:\BM0002\B ...