Java Socket网络编程的经典例子(转)
事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作。Socket就是其中之一,对于Java而言,这些Api存在与java.net 这个包里面,因此只要导入这个包就可以准备网络编程了。
网络编程的基本模型就是客户机到服务器模 型,简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数 据的通讯就可以了,这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端,基于这个简单的模型,就可以进入网络编程啦。
Java对这个模型的支持有很多种Api,而这里我只想介绍有关Socket的编程接口,对于 Java而言已经简化了Socket的编程接口。首先我们来讨论有关提供固定位置的服务方是如何建立的。Java提供了ServerSocket来对其进 行支持.事实上当你创建该类的一个实力对象并提供一个端口资源你就建立了一个固定位置可以让其他计算机来访问你,ServerSocket server=new ServerSocket(6789);这里稍微要注意的是端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从 0~65535之间的,前1024个端口已经被Tcp/Ip 作为保留端口,因此你所分配的端口只能是1024个之后的。好了,我们有了固定位置.现在所需要的就是一根连接线了.该连接线由客户方首先提出要求。因此 Java同样提供了一个Socket对象来对其进行支持,只要客户方创建一个Socket的实例对象进行支持就可以了。Socket client
=new Socket(InetAddress.getLocalHost(),5678);客户机必须知道有关服务器的IP地址,对于着一点Java也提供了一个相关的类InetAddress 该对象的实例必须通过它的静态方法来提供,它的静态方法主要提供了得到本机IP 和通过名字或IP直接得到InetAddress的方法。
上面的方法基本可以建立一条连线让两台计算机相互交流了,可是数据是如何传输的呢?事实上 I/O操作总是和网络编程息息相关的。因为底层的网络是继续数据的,除非远程调用,处理问题的核心在执行上,否则数据的交互还是依赖于IO操作的,所以你 也必须导入java.io这个包.java的IO操作也不复杂,它提供了针对于字节流和Unicode的读者和写者,然后也提供了一个缓冲用于数据的读 写。
BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
上面两句就是建立缓冲并把原始的字节流转变为Unicode可以操作,而原始的字节流来源于 Socket的两个方法,getInputStream()和getOutputStream()方,分别用来得到输入和输出,那么现在有了基本的模型和 基本的操作工具,我们可以做一个简单的Socket例程了.
服务方:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
这个程序的主要目的在于服务器不断接收客户机所写入的信息只到,客户机发送"End"字符串就退出程序,并且服务器也会做出"Receive"为回应,告知客户机已接收到消息。
客户机代码:
import java.net.*;
import java.io.*;
public class Client{
static Socket server;
public static void main(String[] args)throws Exception{
server=new Socket(InetAddress.getLocalHost(),5678);
BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
while(true){
String str=wt.readLine();
out.println(str);
out.flush();
if(str.equals("end")){
break;
}
System.out.println(in.readLine());
}
server.close();
}
}
客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识。
这个程序只是简单的两台计算机之间的通讯,如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的。那么多个客户端如何实现呢?
其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身,而服务器通
过accept方法就是同意和客户建立通讯.这样当客户建立Socket的同时。服务器也会使用这一根连线来先后通讯,那么既然如此只要我们存在多条连线
就可以了。那么我们的程序可以变为如下:
服务器:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
}
这里仅仅只是加了一个外层的While循环,这个循环的目的就是当一个客户进来就为它分配一个
Socket直到这个客户完成一次和服务器的交互,这里也就是接受到客户的"End"消息.那么现在就实现了多客户之间的交互了。但是.问题又来了,这样
做虽然解决了多客户,可是是排队执行的。也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互,无法做到同时服务,那么要如何才
能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了。所以线程是最好的解决方案。
那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系。然
后由线程来执行刚才的操作,要创建线程要么直接继承Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执
行线程就必须重写run方法,而run方法所做的事情就是刚才单线程版本main所做的事情,因此我们的程序变成了这样:
import java.net.*;
import java.io.*;
public class MultiUser extends Thread{
private Socket client;
public MultiUser(Socket c){
this.client=c;
}
public void run(){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
//Mutil User but can't parallel
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}catch(IOException ex){
}finally{
}
}
public static void main(String[] args)throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
//transfer location change Single User or Multi User
MultiUser mu=new MultiUser(server.accept());
mu.start();
}
}
}
我的类直接从Thread类继承了下来.并且通过构造函数传递引用和客户Socket建立了联系,这样每个线程就有了。一个通讯管道.同样我们可以填写run方法,把之前的操作交给线程来完成,这样多客户并行的Socket就建立起来了。
Java Socket网络编程的经典例子(转)的更多相关文章
- Java Socket 网络编程心跳设计概念
Java Socket 网络编程心跳设计概念 1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...
- 循序渐进Java Socket网络编程(多客户端、信息共享、文件传输)
目录[-] 一.TCP/IP协议 二.TCP与UDP 三.Socket是什么 四.Java中的Socket 五.基本的Client/Server程序 六.多客户端连接服务器 七.信息共享 八.文件传输 ...
- Java Socket网络编程学习笔记(一)
0.前言 其实大概半年前就已经看过网络编程Socket的知识了(传统IO),但是因为长时间的不使用导致忘的一干二净,最近正好准备校招,又重新看了网络编程这一章, 是传统IO(BIO)相关的内容,故在此 ...
- Java Socket网络编程Server端详解
Socket通信:分为客户端和服务端的socket代码. Java SDK提供一些相对简单的Api来完成.对于Java而言.这些Api存在与java.net 这个包里面.因此只要导入这个包就可以开始网 ...
- java socket 网络编程常见异常
1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个,一个是connect的时候,这个超时参数由connect(Socket ...
- Java Socket网络编程常见异常(转)
1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个,一个是connect的时候,这个超时参数由connect(Socket ...
- java socket网络编程(多线程技术)
Client.java import java.io.*; import java.net.*; import java.util.*; public class Client { public st ...
- Java Socket网络编程Client端详解
此类实现客户端套接字(也可以就叫“套接字”).套接字是两台机器之间的通信端点. Socket client = new Socket(ip,port);//创建一个流套接字并将其连接到指定 IP 地址 ...
- java基础-网络编程(Socket)技术选型入门之NIO技术
java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...
随机推荐
- ArrayList其实就那么一回事儿之源码浅析
ArrayList 算是常用的集合之一了,不知作为javaner的你有没在百忙之中抽出一点时间看看ArrayList的源码呢. 如果看了,你会觉得其实ArrayList其实就那么一回事儿,对吧,下面就 ...
- bzoj 3170: [Tjoi 2013]松鼠聚会
#include<cstdio> #include<iostream> #include<algorithm> #define M 100008 using nam ...
- movebase导航
利用turtlebot 的导航配置文件 由于movbase发的速度太不友好了所以使用了ros自带的滤波安装相应的包 apt-get install ros-indigo-yocs-velocity-s ...
- 在Eclipse上建立hadoop2.2.0/hadoop2.4.0源代码阅读环境
1.安装依赖的包: yum install gcc-c++ g++ autoconf automake libtool cmake zlib1g-dev pkg-config libssl-dev 2 ...
- Windows 95 vs. Windows 10
- 开发者如何利用工具快速开发出完美APP
文|移动互联网李建华 微信:ydhlwdyq 传统的个人开发者,要想开发出一个完美的APP要 经过以下几个过程:搭建开发环境,写代码,写统计系统,开发即将完成后,要购买服务器,然后把程序布置到服务器上 ...
- 探索javascript----获得节点计算后样式
节点计算后样式是一个属性与属性值的值对对象: IE: node.currentStyle; 非IE: window.getComputedStyle(node,null); 兼容方式: func ...
- sass安装 使用
一 什么是sass sass是一种css开发工具.提供了很多便利的写法,使得css开发变得简单 易维护 sass有两种后缀名文件:一种后缀名为sass,不使用大括号和分号:另一 ...
- Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:
Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长: 通过Hibernate注解的方式映射oracel数据库的sequence主键生成器 ...
- 收集的maven 仓库地址(maven repository)
maven 仓库地址: 共有的仓库http://repo1.maven.org/maven2/http://repository.jboss.com/maven2/http://repository. ...