接触java几个月了,说来惭愧,由于项目原因以及个人原因= =、并没有接触到socket等网络编程的东西。文章非原创,度娘了几篇文章,查阅了一点资料,在这里做一个简单整合介绍。
(感谢原作者们的无私奉献)
socket 简介
1. 什么是socket
socket 源于Berkeley Socket,是Berkeley Unix中使用的TCP socket原语。现在被广泛应用于Internet程序设计中。
根据wiki百科的介绍
维基百科介绍说socket是计算机网络中进程间通信的终端。多句嘴,互联网的通信是电脑与电脑之间的通信,而电脑之间的通信是端口与端口之间的通信。而socket则对应于某台主机的某个端口。
socket API 用于操作网络中的sockets,API是基于Berkeley sockets标准的。
socket地址是由主机IP + 端口号组成的。基于该地址,网络socket可以给进程或者线程传输数据。
进入正题:
事实上网络编程简单的理解就是两台计算机相互通讯数据而已.对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了.Java SDK提供一些相对简单的Api来完成这些工作.Socket就是其中之一.对于Java而言.这些Api存在与java.net 这个包里面.因此只要导入这个包就可以准备网络编程了.
网络编程的基本模型就是客户机到服务器模型(游戏玩家应该不会陌生,服务器端 与 客户端 即CS模型)。简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置(服务器端,供人访问),而另一个(客户端,去访问服务器)则只需要知道这个固定的位置.并去建立两者之间的联系..然后完成数据的通讯就可以了.这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端.基于这个简单的模型,就可以进入网络编程啦.
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而说都是一样的,都是放在流里的).除非远程调用,处理问题的核心在执行上.否则数据的交互还是依赖于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例程了. (关于流IO的一些基础,可以参见po主的另一篇IO的博文)
服务方:
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(); } }
这里稍微详细一点的介绍一下服务器端的功能:
MyServer类中包含两个socket成员变量,一个ServerSocket :server ; 一个Socket : client。
socket上面简单介绍过了,看这个serverSocket的作用。根据JDK1.7 ServerSocket位于java.net包下面,包含的成员方法有:accept、bind、close等控制方法以及getChannel、getLocalPort等取状态方法。并不包含通信方法。所以可以确定的是,ServerSocket是用于服务器端(顾名思义)的主要用来控制访问的类,并不用于通信。再看accept方法
Listens for a connection to be made to this socket and accepts it.
服务器用来监听网路,如没有响应便一直赌赛,一旦有连接响应便接收,并创建一个与之会话的socket(大家可以做个试验,取返回的这个socket的IP 和 端口号,看是否是服务器IP + 上文中申请的6789端口)
接下来对client.getInputStream流进行封装,细节可以参考IO博文,我们暂时把这条连接称之为 会话 。且看client.getInputStream,即从会话中拿到的数据,当然了,这数据是客户端放到会话中的。while循环中,服务器的工作就是,从客户端拿到输入流,打印出来,再将字符串“has receive...”输出到会话中,一旦Myserver从会话中拿到end就跳出循环,并将会话关闭。
客户机代码:
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(); } }
客户端的代码,首先看wt,即接受从控制台输入的数据,并将其放入对话中(相对于自己是输出),然后打印出会话中的信息。(简单的流程是,客户往会话中输入数据“。。。”,服务器端从会话中将该数据取出,并打印出,然后服务器将“has receive....”输入到会话中,客户端从会话中将“has receive...”取出,并打印出来,此流程一直循环到客户端输入“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编程详解及实例分析 #### 一、Socket编程基础概述 在计算机网络通信领域,Socket编程是一种广泛使用的通信方式。它为不同主机上的进程提供了双向通信的能力,是网络编程的基础之一。Java语言提供了...
Java套接字(Socket)编程是Java网络编程的基础,它提供了客户端与服务器之间的通信机制。在《Java大学教程》中,通常会通过实例来详细解释和演示这些概念。本实例集中,我们关注的是三个关键的Socket编程示例,旨在...
Java Socket网络编程是Java平台中的核心特性,它为开发者提供了在TCP/IP协议下创建网络应用的能力。Socket编程主要用于实现客户端和服务器之间的通信,基于客户机/服务器模型。在这个模型中,服务器端通常处于被动...
总的来说,Java Socket网络编程是构建网络应用的基础,无论是简单的文件传输、聊天应用,还是复杂的分布式系统,都离不开Socket的使用。通过理解和实践TCP和UDP的Socket编程,开发者能够更好地掌握网络通信的核心...
Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,编程实例Socket,...
java socket 实现简单的客户端和服务端通信
### Java Socket 编程实例详解 #### 一、引言 在现代软件开发中,网络编程占据了极其重要的地位。无论是互联网应用还是企业级系统,都需要处理不同设备间的通信。Java作为一种广泛使用的编程语言,提供了强大的...
Java Socket编程是网络编程的基础,它提供了在两个应用程序之间建立通信连接的能力。在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库...
MFC socket 服务器端编程实例MFC socket 服务器端编程实例MFC socket 服务器端编程实例MFC socket 服务器端编程实例MFC socket 服务器端编程实例MFC socket 服务器端编程实例
Java Socket编程是Java平台中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的、面向连接的、可靠的字节流通信。在本文中,我们将深入探讨Java Socket编程的关键概念、工作原理以及如何创建服务端和...
总之,Socket高级编程实例是一个非常有价值的资源,它可以帮助学习者巩固理论知识,提升实战技能,为成为专业的网络程序员奠定坚实基础。在学习过程中,不断实践和调试代码,理解网络通信的本质,将使你在网络编程...
总之,这个C#的Socket编程实例展示了如何构建一个简单的聊天应用程序,涉及了Socket的基本操作,包括连接、监听、发送和接收数据。通过理解和实践这个示例,开发者可以深入理解网络编程的基础,并为开发更复杂的网络...
Java Socket是Java编程语言中实现网络通信的基础组件,它提供了应用程序与网络协议的接口,使得开发者可以构建基于TCP(传输控制协议)或UDP(用户数据报协议)的应用程序。本教程将深入探讨Java Socket编程的核心...
Java Socket编程是网络编程中的重要组成部分,主要用于实现...总的来说,Java Socket编程是构建分布式系统、实现客户端与服务器间数据交换的基础。通过深入理解和实践,开发者可以构建出高效、稳定的网络应用程序。
Java套接字(Socket)编程是网络编程的基础,它提供了应用程序之间进行低级通信的端点。在Java中,Socket类代表一个网络连接的端点,而ServerSocket类用于监听客户端的连接请求。本实例代码是为了配合博客文章,提供...
Java Socket网络编程是Java开发中一个重要...Java Socket编程是构建网络应用的基础,掌握其原理和实践方法对于开发分布式系统、网络服务等至关重要。通过不断实践和学习,开发者可以更熟练地运用Socket来解决实际问题。
在Android平台上进行网络通信时,Socket编程是一种常见...总之,Android Socket编程实例涵盖了网络通信的基础知识,包括建立连接、传输数据和管理连接等。理解并掌握这些知识,将有助于你构建功能完善的网络通信应用。
Java Socket编程是网络编程的基础,它提供了进程间通信(IPC)的能力,特别是在互联网环境中,让两个运行在不同设备上的应用程序可以相互通信。本实例压缩包包含了一系列的Java Socket编程示例,旨在帮助开发者深入...
Java Socket 编程总结 Java Socket 编程是Java语言中用于网络编程的主要技术之一。它允许开发者创建网络应用程序,通过Socket实现客户机/服务器结构的通信。在Java中,Socket编程主要是基于TCP/IP协议的网络编程。 ...
Java之Socket编程是网络通信中的基础,主要用于实现客户端与服务器之间的连接。在这个简单实例中,我们将探讨如何使用Java的Socket和ServerSocket类来构建一个基本的客户端-服务器通信模型。 首先,`ServerSocket`...