- 浏览: 192183 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
一、TCP/IP协议
既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输。这里就要使用到TCP/IP协议。
TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成。IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机。TCP层负责面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象。
二、TCP与UDP
TCP是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP与UDP区别:
TCP特点:
1、TCP是面向连接的协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接协议,所以只能用于点对点的通讯。而且建立连接也需要消耗时间和开销。
2、TCP传输数据无大小限制,进行大数据传输。
3、TCP是一个可靠的协议,它能保证接收方能够完整正确地接收到发送方发送的全部数据。
UDP特点:
1、UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。
2、UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。
3、UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。
TCP与UDP应用:
1、TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。
2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。
三、Socket是什么
Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
Socket通讯过程:服务端监听某个端口是否有连接请求,客户端向服务端发送连接请求,服务端收到连接请求向客户端发出接收消息,这样一个连接就建立起来了。客户端和服务端都可以相互发送消息与对方进行通讯。
Socket的基本工作过程包含以下四个步骤:
1、创建Socket;
2、打开连接到Socket的输入输出流;
3、按照一定的协议对Socket进行读写操作;
4、关闭Socket。
四、Java中的Socket
在java.net包下有两个类:Socket和ServerSocket。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
列出几个常用的构造方法:
Socket(InetAddress address,int port);//创建一个流套接字并将其连接到指定 IP 地址的指定端口号
Socket(String host,int port);//创建一个流套接字并将其连接到指定主机上的指定端口号
Socket(InetAddress address,int port, InetAddress localAddr,int localPort);//创建一个套接字并将其连接到指定远程地址上的指定远程端口
Socket(String host,int port, InetAddress localAddr,int localPort);//创建一个套接字并将其连接到指定远程主机上的指定远程端口
Socket(SocketImpl impl);//使用用户指定的 SocketImpl 创建一个未连接 Socket
ServerSocket(int port);//创建绑定到特定端口的服务器套接字
ServerSocket(int port,int backlog);//利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号
ServerSocket(int port,int backlog, InetAddress bindAddr);//使用指定的端口、侦听 backlog 和要绑定到的本地 IP地址创建服务器
构造方法的参数中,address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。
注意:必须小心选择端口号。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。
几个重要的Socke方法:
public InputStream getInputStream();//方法获得网络连接输入,同时返回一个IutputStream对象实例
public OutputStream getOutputStream();//方法连接的另一端将得到输入,同时返回一个OutputStream对象实例
public Socket accept();//用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。
"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
TCP的Java支持
协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为流套接字(使用TCP协议)和数据报套接字(使用UDP协议)。
TCP协议提供面向连接的服务,通过它建立的是可靠地连接。Java为TCP协议提供了两个类:Socket类和ServerSocket类。一个Socket实例代表了TCP连接的一个客户端,而一个ServerSocket实例代表了TCP连接的一个服务器端,一般在TCP Socket编程中,客户端有多个,而服务器端只有一个,客户端TCP向服务器端TCP发送连接请求,服务器端的ServerSocket实例则监听来自客户端的TCP连接请求,并为每个请求创建新的Socket实例,由于服务端在调用accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个Socket连接开启一个线程。服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。另外,每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。
TCP连接的建立步骤
客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的TCP客户端要经过下面三步操作:
1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;
2.通过套接字的I/O流与服务端通信;
3、使用Socket类的close方法关闭连接。
服务端的工作是建立一个通信终端,并被动地等待客户端的连接。典型的TCP服务端执行如下两步操作:
1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
2、重复执行:
1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;
3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。
五、基本的Client/Server程序
以下是一个基本的客户端/服务器端程序代码。主要实现了服务器端一直监听某个端口,等待客户端连接请求。客户端根据IP地址和端口号连接服务器端,从键盘上输入一行信息,发送到服务器端,然后接收服务器端返回的信息,最后结束会话。这个程序一次只能接受一个客户连接。
ps:这个小例子写好后,服务端一直接收不到消息,调试了好长时间,才发现误使用了PrintWriter的print()方法,而BufferedReader的readLine()方法一直没有遇到换行,所以一直等待读取。我晕死~~@_@
客户端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) {
try {
/** 创建Socket*/
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号(本处是本机)
Socket socket =new Socket("127.0.0.1",2013);
// 60s超时
socket.setSoTimeout(60000);
/** 发送客户端准备传输的信息 */
// 由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
// 将输入读入的字符串输出到Server
BufferedReader sysBuff =new BufferedReader(new InputStreamReader(System.in));
printWriter.println(sysBuff.readLine());
// 刷新输出流,使Server马上收到该字符串
printWriter.flush();
/** 用于获取服务端传输来的信息 */
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 输入读入一字符串
String result = bufferedReader.readLine();
System.out.println("Server say : " + result);
/** 关闭Socket*/
printWriter.close();
bufferedReader.close();
socket.close();
}catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
服务器端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) {
try {
/** 创建ServerSocket*/
// 创建一个ServerSocket在端口2013监听客户请求
ServerSocket serverSocket =new ServerSocket(2013);
while (true) {
// 侦听并接受到此Socket的连接,请求到来则产生一个Socket对象,并继续执行
Socket socket = serverSocket.accept();
/** 获取客户端传来的信息 */
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 获取从客户端读入的字符串
String result = bufferedReader.readLine();
System.out.println("Client say : " + result);
/** 发送服务端准备传输的 */
// 由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter printWriter =new PrintWriter(socket.getOutputStream());
printWriter.print("hello Client, I am Server!");
printWriter.flush();
/** 关闭Socket*/
printWriter.close();
bufferedReader.close();
socket.close();
}
}catch (Exception e) {
System.out.println("Exception:" + e);
}finally{
// serverSocket.close();
}
}
}
六、多客户端连接服务器
上面的服务器端程序一次只能连接一个客户端,这在实际应用中显然是不可能的。通常的网络环境是多个客户端连接到某个主机进行通讯,所以我们要对上面的程序进行改造。
设计思路:服务器端主程序监听某一个端口,客户端发起连接请求,服务器端主程序接收请求,同时构造一个线程类,用于接管会话。当一个Socket会话产生后,这个会话就会交给线程进行处理,主程序继续进行监听。
下面的实现程序流程是:客户端和服务器建立连接,客户端发送消息,服务端根据消息进行处理并返回消息,若客户端申请关闭,则服务器关闭此连接,双方通讯结束。
客户端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) {
try {
Socket socket =new Socket("127.0.0.1",2013);
socket.setSoTimeout(60000);
PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
String result ="";
while(result.indexOf("bye") == -1){
BufferedReader sysBuff =new BufferedReader(new InputStreamReader(System.in));
printWriter.println(sysBuff.readLine());
printWriter.flush();
result = bufferedReader.readLine();
System.out.println("Server say : " + result);
}
printWriter.close();
bufferedReader.close();
socket.close();
}catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
服务器端程序:
package sock;
import java.io.*;
import java.net.*;
public class Server extends ServerSocket {
private static final int SERVER_PORT =2013;
public Server()throws IOException {
super(SERVER_PORT);
try {
while (true) {
Socket socket = accept();
new CreateServerThread(socket);//当有请求时,启一个线程处理
}
}catch (IOException e) {
}finally {
close();
}
}
//线程类
class CreateServerThread extends Thread {
private Socket client;
private BufferedReader bufferedReader;
private PrintWriter printWriter;
public CreateServerThread(Socket s)throws IOException {
client = s;
bufferedReader =new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter =new PrintWriter(client.getOutputStream(),true);
System.out.println("Client(" + getName() +") come in...");
start();
}
public void run() {
try {
String line = bufferedReader.readLine();
while (!line.equals("bye")) {
printWriter.println("continue, Client(" + getName() +")!");
line = bufferedReader.readLine();
System.out.println("Client(" + getName() +") say: " + line);
}
printWriter.println("bye, Client(" + getName() +")!");
System.out.println("Client(" + getName() +") exit!");
printWriter.close();
bufferedReader.close();
client.close();
}catch (IOException e) {
}
}
}
public static void main(String[] args)throws IOException {
new Server();
}
}
七、信息共享
以上虽然实现了多个客户端和服务器连接,但是仍然是消息在一个客户端和服务器之间相互传播。现在我们要实现信息共享,即服务器可以向多个客户端发送广播消息,客户端也可以向其他客户端发送消息。类似于聊天室的那种功能,实现信息能在多个客户端之间共享。
设计思路:客户端循环可以不停输入向服务器发送消息,并且启一个线程,专门用来监听服务器端发来的消息并打印输出。服务器端启动时,启动一个监听何时需要向客户端发送消息的线程。每次接受客户端连接请求,都启一个线程进行处理,并且将客户端信息存放到公共集合中。当客户端发送消息时,服务器端将消息顺序存入队列中,当需要输出时,从队列中取出广播到各客户端处。客户端输入showuser命令可以查看在线用户列表,输入bye向服务器端申请退出连接。
PS:以下代码在测试时发现了一个中文乱码小问题,当文件设置UTF-8编码时,无论怎样在代码中设置输入流编码都不起作用,输入中文仍然会乱码。把文件设置为GBK编码后,不用在代码中设置输入流编码都能正常显示传输中文。
客户端代码:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient extends Socket{
private static final String SERVER_IP ="127.0.0.1";
private static final int SERVER_PORT =2013;
private Socket client;
private PrintWriter out;
private BufferedReader in;
/**
* 与服务器连接,并输入发送消息
*/
public SocketClient()throws Exception{
super(SERVER_IP, SERVER_PORT);
client =this;
out =new PrintWriter(this.getOutputStream(),true);
in =new BufferedReader(new InputStreamReader(this.getInputStream()));
new readLineThread();
while(true){
in =new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();
out.println(input);
}
}
/**
* 用于监听服务器端向客户端发送消息线程类
*/
class readLineThread extends Thread{
private BufferedReader buff;
public readLineThread(){
try {
buff =new BufferedReader(new InputStreamReader(client.getInputStream()));
start();
}catch (Exception e) {
}
}
@Override
public void run() {
try {
while(true){
String result = buff.readLine();
if("byeClient".equals(result)){//客户端申请退出,服务端返回确认退出
break;
}else{//输出服务端发送消息
System.out.println(result);
}
}
in.close();
out.close();
client.close();
}catch (Exception e) {
}
}
}
public static void main(String[] args) {
try {
new SocketClient();//启动客户端
}catch (Exception e) {
}
}
}
服务器端代码:
package sock;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Server extends ServerSocket{
private static final int SERVER_PORT =2013;
private static boolean isPrint =false;//是否输出消息标志
private static List user_list =new ArrayList();//登录用户集合
private static List<ServerThread> thread_list =new ArrayList<ServerThread>();//服务器已启用线程集合
private static LinkedList<String> message_list =new LinkedList<String>();//存放消息队列
/**
* 创建服务端Socket,创建向客户端发送消息线程,监听客户端请求并处理
*/
public Server()throws IOException{
super(SERVER_PORT);//创建ServerSocket
new PrintOutThread();//创建向客户端发送消息线程
try {
while(true){//监听客户端请求,启个线程处理
Socket socket = accept();
new ServerThread(socket);
}
}catch (Exception e) {
}finally{
close();
}
}
/**
* 监听是否有输出消息请求线程类,向客户端发送消息
*/
class PrintOutThread extends Thread{
public PrintOutThread(){
start();
}
@Override
public void run() {
while(true){
if(isPrint){//将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。
String message = message_list.getFirst();
for (ServerThread thread : thread_list) {
thread.sendMessage(message);
}
message_list.removeFirst();
isPrint = message_list.size() >0 ?true :false;
}
}
}
}
/**
* 服务器线程类
*/
class ServerThread extends Thread{
private Socket client;
private PrintWriter out;
private BufferedReader in;
private String name;
public ServerThread(Socket s)throws IOException{
client = s;
out =new PrintWriter(client.getOutputStream(),true);
in =new BufferedReader(new InputStreamReader(client.getInputStream()));
in.readLine();
out.println("成功连上聊天室,请输入你的名字:");
start();
}
@Override
public void run() {
try {
int flag =0;
String line = in.readLine();
while(!"bye".equals(line)){
//查看在线用户列表
if ("showuser".equals(line)) {
out.println(this.listOnlineUsers());
line = in.readLine();
}
//第一次进入,保存名字
if(flag++ ==0){
name = line;
user_list.add(name);
thread_list.add(this);
out.println(name +"你好,可以开始聊天了...");
this.pushMessage("Client<" + name +">进入聊天室...");
}else{
this.pushMessage("Client<" + name +"> say : " + line);
}
line = in.readLine();
}
out.println("byeClient");
}catch (Exception e) {
e.printStackTrace();
}finally{//用户退出聊天室
try {
client.close();
}catch (IOException e) {
e.printStackTrace();
}
thread_list.remove(this);
user_list.remove(name);
pushMessage("Client<" + name +">退出了聊天室");
}
}
//放入消息队列末尾,准备发送给客户端
private void pushMessage(String msg){
message_list.addLast(msg);
isPrint =true;
}
//向客户端发送一条消息
private void sendMessage(String msg){
out.println(msg);
}
//统计在线用户列表
private String listOnlineUsers() {
String s ="--- 在线用户列表 ---\015\012";
for (int i =0; i < user_list.size(); i++) {
s +="[" + user_list.get(i) +"]\015\012";
}
s +="--------------------";
return s;
}
}
public static void main(String[] args)throws IOException {
new Server();//启动服务端
}
}
八、文件传输
客户端向服务器端传送文件,服务端可获取文件名用于保存,获取文件大小计算传输进度,比较简单,直接贴代码。
客户端代码:
package sock;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;
/**
* 客户端
*/
public class Client extends Socket{
private static final String SERVER_IP ="127.0.0.1";
private static final int SERVER_PORT =2013;
private Socket client;
private FileInputStream fis;
private DataOutputStream dos;
public Client(){
try {
try {
client =new Socket(SERVER_IP, SERVER_PORT);
//向服务端传送文件
File file =new File("c:/test.doc");
fis =new FileInputStream(file);
dos =new DataOutputStream(client.getOutputStream());
//文件名和长度
dos.writeUTF(file.getName());
dos.flush();
dos.writeLong(file.length());
dos.flush();
//传输文件
byte[] sendBytes =new byte[1024];
int length =0;
while((length = fis.read(sendBytes,0, sendBytes.length)) >0){
dos.write(sendBytes,0, length);
dos.flush();
}
}catch (Exception e) {
e.printStackTrace();
}finally{
if(fis !=null)
fis.close();
if(dos !=null)
dos.close();
client.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception {
new Client();
}
}
服务器端代码:
package sock;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器
*/
public class Server extends ServerSocket{
private static final int PORT =2013;
private ServerSocket server;
private Socket client;
private DataInputStream dis;
private FileOutputStream fos;
public Server()throws Exception{
try {
try {
server =new ServerSocket(PORT);
while(true){
client = server.accept();
dis =new DataInputStream(client.getInputStream());
//文件名和长度
String fileName = dis.readUTF();
long fileLength = dis.readLong();
fos =new FileOutputStream(new File("d:/" + fileName));
byte[] sendBytes =new byte[1024];
int transLen =0;
System.out.println("----开始接收文件<" + fileName +">,文件大小为<" + fileLength +">----");
while(true){
int read =0;
read = dis.read(sendBytes);
if(read == -1)
break;
transLen += read;
System.out.println("接收文件进度" +100 * transLen/fileLength +"%...");
fos.write(sendBytes,0, read);
fos.flush();
}
System.out.println("----接收文件<" + fileName +">成功-------");
client.close();
}
}catch (Exception e) {
e.printStackTrace();
}finally {
if(dis !=null)
dis.close();
if(fos !=null)
fos.close();
server.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception {
new Server();
}
}
转自http://my.oschina.net/leejun2005/blog/104955
既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输。这里就要使用到TCP/IP协议。
TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成。IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机。TCP层负责面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象。
二、TCP与UDP
TCP是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP与UDP区别:
TCP特点:
1、TCP是面向连接的协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接协议,所以只能用于点对点的通讯。而且建立连接也需要消耗时间和开销。
2、TCP传输数据无大小限制,进行大数据传输。
3、TCP是一个可靠的协议,它能保证接收方能够完整正确地接收到发送方发送的全部数据。
UDP特点:
1、UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。
2、UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。
3、UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。
TCP与UDP应用:
1、TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。
2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。
三、Socket是什么
Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
Socket通讯过程:服务端监听某个端口是否有连接请求,客户端向服务端发送连接请求,服务端收到连接请求向客户端发出接收消息,这样一个连接就建立起来了。客户端和服务端都可以相互发送消息与对方进行通讯。
Socket的基本工作过程包含以下四个步骤:
1、创建Socket;
2、打开连接到Socket的输入输出流;
3、按照一定的协议对Socket进行读写操作;
4、关闭Socket。
四、Java中的Socket
在java.net包下有两个类:Socket和ServerSocket。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
列出几个常用的构造方法:
Socket(InetAddress address,int port);//创建一个流套接字并将其连接到指定 IP 地址的指定端口号
Socket(String host,int port);//创建一个流套接字并将其连接到指定主机上的指定端口号
Socket(InetAddress address,int port, InetAddress localAddr,int localPort);//创建一个套接字并将其连接到指定远程地址上的指定远程端口
Socket(String host,int port, InetAddress localAddr,int localPort);//创建一个套接字并将其连接到指定远程主机上的指定远程端口
Socket(SocketImpl impl);//使用用户指定的 SocketImpl 创建一个未连接 Socket
ServerSocket(int port);//创建绑定到特定端口的服务器套接字
ServerSocket(int port,int backlog);//利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号
ServerSocket(int port,int backlog, InetAddress bindAddr);//使用指定的端口、侦听 backlog 和要绑定到的本地 IP地址创建服务器
构造方法的参数中,address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创建Socket。count则表示服务端所能支持的最大连接数。
注意:必须小心选择端口号。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。
几个重要的Socke方法:
public InputStream getInputStream();//方法获得网络连接输入,同时返回一个IutputStream对象实例
public OutputStream getOutputStream();//方法连接的另一端将得到输入,同时返回一个OutputStream对象实例
public Socket accept();//用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。
"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
TCP的Java支持
协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构、交换方式、包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议、TCP协议和UDP协议。现在TCP/IP协议族中的主要socket类型为流套接字(使用TCP协议)和数据报套接字(使用UDP协议)。
TCP协议提供面向连接的服务,通过它建立的是可靠地连接。Java为TCP协议提供了两个类:Socket类和ServerSocket类。一个Socket实例代表了TCP连接的一个客户端,而一个ServerSocket实例代表了TCP连接的一个服务器端,一般在TCP Socket编程中,客户端有多个,而服务器端只有一个,客户端TCP向服务器端TCP发送连接请求,服务器端的ServerSocket实例则监听来自客户端的TCP连接请求,并为每个请求创建新的Socket实例,由于服务端在调用accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个Socket连接开启一个线程。服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。另外,每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。
TCP连接的建立步骤
客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的TCP客户端要经过下面三步操作:
1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;
2.通过套接字的I/O流与服务端通信;
3、使用Socket类的close方法关闭连接。
服务端的工作是建立一个通信终端,并被动地等待客户端的连接。典型的TCP服务端执行如下两步操作:
1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
2、重复执行:
1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;
3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。
五、基本的Client/Server程序
以下是一个基本的客户端/服务器端程序代码。主要实现了服务器端一直监听某个端口,等待客户端连接请求。客户端根据IP地址和端口号连接服务器端,从键盘上输入一行信息,发送到服务器端,然后接收服务器端返回的信息,最后结束会话。这个程序一次只能接受一个客户连接。
ps:这个小例子写好后,服务端一直接收不到消息,调试了好长时间,才发现误使用了PrintWriter的print()方法,而BufferedReader的readLine()方法一直没有遇到换行,所以一直等待读取。我晕死~~@_@
客户端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) {
try {
/** 创建Socket*/
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号(本处是本机)
Socket socket =new Socket("127.0.0.1",2013);
// 60s超时
socket.setSoTimeout(60000);
/** 发送客户端准备传输的信息 */
// 由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
// 将输入读入的字符串输出到Server
BufferedReader sysBuff =new BufferedReader(new InputStreamReader(System.in));
printWriter.println(sysBuff.readLine());
// 刷新输出流,使Server马上收到该字符串
printWriter.flush();
/** 用于获取服务端传输来的信息 */
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 输入读入一字符串
String result = bufferedReader.readLine();
System.out.println("Server say : " + result);
/** 关闭Socket*/
printWriter.close();
bufferedReader.close();
socket.close();
}catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
服务器端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) {
try {
/** 创建ServerSocket*/
// 创建一个ServerSocket在端口2013监听客户请求
ServerSocket serverSocket =new ServerSocket(2013);
while (true) {
// 侦听并接受到此Socket的连接,请求到来则产生一个Socket对象,并继续执行
Socket socket = serverSocket.accept();
/** 获取客户端传来的信息 */
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 获取从客户端读入的字符串
String result = bufferedReader.readLine();
System.out.println("Client say : " + result);
/** 发送服务端准备传输的 */
// 由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter printWriter =new PrintWriter(socket.getOutputStream());
printWriter.print("hello Client, I am Server!");
printWriter.flush();
/** 关闭Socket*/
printWriter.close();
bufferedReader.close();
socket.close();
}
}catch (Exception e) {
System.out.println("Exception:" + e);
}finally{
// serverSocket.close();
}
}
}
六、多客户端连接服务器
上面的服务器端程序一次只能连接一个客户端,这在实际应用中显然是不可能的。通常的网络环境是多个客户端连接到某个主机进行通讯,所以我们要对上面的程序进行改造。
设计思路:服务器端主程序监听某一个端口,客户端发起连接请求,服务器端主程序接收请求,同时构造一个线程类,用于接管会话。当一个Socket会话产生后,这个会话就会交给线程进行处理,主程序继续进行监听。
下面的实现程序流程是:客户端和服务器建立连接,客户端发送消息,服务端根据消息进行处理并返回消息,若客户端申请关闭,则服务器关闭此连接,双方通讯结束。
客户端程序:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) {
try {
Socket socket =new Socket("127.0.0.1",2013);
socket.setSoTimeout(60000);
PrintWriter printWriter =new PrintWriter(socket.getOutputStream(),true);
BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(socket.getInputStream()));
String result ="";
while(result.indexOf("bye") == -1){
BufferedReader sysBuff =new BufferedReader(new InputStreamReader(System.in));
printWriter.println(sysBuff.readLine());
printWriter.flush();
result = bufferedReader.readLine();
System.out.println("Server say : " + result);
}
printWriter.close();
bufferedReader.close();
socket.close();
}catch (Exception e) {
System.out.println("Exception:" + e);
}
}
}
服务器端程序:
package sock;
import java.io.*;
import java.net.*;
public class Server extends ServerSocket {
private static final int SERVER_PORT =2013;
public Server()throws IOException {
super(SERVER_PORT);
try {
while (true) {
Socket socket = accept();
new CreateServerThread(socket);//当有请求时,启一个线程处理
}
}catch (IOException e) {
}finally {
close();
}
}
//线程类
class CreateServerThread extends Thread {
private Socket client;
private BufferedReader bufferedReader;
private PrintWriter printWriter;
public CreateServerThread(Socket s)throws IOException {
client = s;
bufferedReader =new BufferedReader(new InputStreamReader(client.getInputStream()));
printWriter =new PrintWriter(client.getOutputStream(),true);
System.out.println("Client(" + getName() +") come in...");
start();
}
public void run() {
try {
String line = bufferedReader.readLine();
while (!line.equals("bye")) {
printWriter.println("continue, Client(" + getName() +")!");
line = bufferedReader.readLine();
System.out.println("Client(" + getName() +") say: " + line);
}
printWriter.println("bye, Client(" + getName() +")!");
System.out.println("Client(" + getName() +") exit!");
printWriter.close();
bufferedReader.close();
client.close();
}catch (IOException e) {
}
}
}
public static void main(String[] args)throws IOException {
new Server();
}
}
七、信息共享
以上虽然实现了多个客户端和服务器连接,但是仍然是消息在一个客户端和服务器之间相互传播。现在我们要实现信息共享,即服务器可以向多个客户端发送广播消息,客户端也可以向其他客户端发送消息。类似于聊天室的那种功能,实现信息能在多个客户端之间共享。
设计思路:客户端循环可以不停输入向服务器发送消息,并且启一个线程,专门用来监听服务器端发来的消息并打印输出。服务器端启动时,启动一个监听何时需要向客户端发送消息的线程。每次接受客户端连接请求,都启一个线程进行处理,并且将客户端信息存放到公共集合中。当客户端发送消息时,服务器端将消息顺序存入队列中,当需要输出时,从队列中取出广播到各客户端处。客户端输入showuser命令可以查看在线用户列表,输入bye向服务器端申请退出连接。
PS:以下代码在测试时发现了一个中文乱码小问题,当文件设置UTF-8编码时,无论怎样在代码中设置输入流编码都不起作用,输入中文仍然会乱码。把文件设置为GBK编码后,不用在代码中设置输入流编码都能正常显示传输中文。
客户端代码:
package sock;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SocketClient extends Socket{
private static final String SERVER_IP ="127.0.0.1";
private static final int SERVER_PORT =2013;
private Socket client;
private PrintWriter out;
private BufferedReader in;
/**
* 与服务器连接,并输入发送消息
*/
public SocketClient()throws Exception{
super(SERVER_IP, SERVER_PORT);
client =this;
out =new PrintWriter(this.getOutputStream(),true);
in =new BufferedReader(new InputStreamReader(this.getInputStream()));
new readLineThread();
while(true){
in =new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();
out.println(input);
}
}
/**
* 用于监听服务器端向客户端发送消息线程类
*/
class readLineThread extends Thread{
private BufferedReader buff;
public readLineThread(){
try {
buff =new BufferedReader(new InputStreamReader(client.getInputStream()));
start();
}catch (Exception e) {
}
}
@Override
public void run() {
try {
while(true){
String result = buff.readLine();
if("byeClient".equals(result)){//客户端申请退出,服务端返回确认退出
break;
}else{//输出服务端发送消息
System.out.println(result);
}
}
in.close();
out.close();
client.close();
}catch (Exception e) {
}
}
}
public static void main(String[] args) {
try {
new SocketClient();//启动客户端
}catch (Exception e) {
}
}
}
服务器端代码:
package sock;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Server extends ServerSocket{
private static final int SERVER_PORT =2013;
private static boolean isPrint =false;//是否输出消息标志
private static List user_list =new ArrayList();//登录用户集合
private static List<ServerThread> thread_list =new ArrayList<ServerThread>();//服务器已启用线程集合
private static LinkedList<String> message_list =new LinkedList<String>();//存放消息队列
/**
* 创建服务端Socket,创建向客户端发送消息线程,监听客户端请求并处理
*/
public Server()throws IOException{
super(SERVER_PORT);//创建ServerSocket
new PrintOutThread();//创建向客户端发送消息线程
try {
while(true){//监听客户端请求,启个线程处理
Socket socket = accept();
new ServerThread(socket);
}
}catch (Exception e) {
}finally{
close();
}
}
/**
* 监听是否有输出消息请求线程类,向客户端发送消息
*/
class PrintOutThread extends Thread{
public PrintOutThread(){
start();
}
@Override
public void run() {
while(true){
if(isPrint){//将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。
String message = message_list.getFirst();
for (ServerThread thread : thread_list) {
thread.sendMessage(message);
}
message_list.removeFirst();
isPrint = message_list.size() >0 ?true :false;
}
}
}
}
/**
* 服务器线程类
*/
class ServerThread extends Thread{
private Socket client;
private PrintWriter out;
private BufferedReader in;
private String name;
public ServerThread(Socket s)throws IOException{
client = s;
out =new PrintWriter(client.getOutputStream(),true);
in =new BufferedReader(new InputStreamReader(client.getInputStream()));
in.readLine();
out.println("成功连上聊天室,请输入你的名字:");
start();
}
@Override
public void run() {
try {
int flag =0;
String line = in.readLine();
while(!"bye".equals(line)){
//查看在线用户列表
if ("showuser".equals(line)) {
out.println(this.listOnlineUsers());
line = in.readLine();
}
//第一次进入,保存名字
if(flag++ ==0){
name = line;
user_list.add(name);
thread_list.add(this);
out.println(name +"你好,可以开始聊天了...");
this.pushMessage("Client<" + name +">进入聊天室...");
}else{
this.pushMessage("Client<" + name +"> say : " + line);
}
line = in.readLine();
}
out.println("byeClient");
}catch (Exception e) {
e.printStackTrace();
}finally{//用户退出聊天室
try {
client.close();
}catch (IOException e) {
e.printStackTrace();
}
thread_list.remove(this);
user_list.remove(name);
pushMessage("Client<" + name +">退出了聊天室");
}
}
//放入消息队列末尾,准备发送给客户端
private void pushMessage(String msg){
message_list.addLast(msg);
isPrint =true;
}
//向客户端发送一条消息
private void sendMessage(String msg){
out.println(msg);
}
//统计在线用户列表
private String listOnlineUsers() {
String s ="--- 在线用户列表 ---\015\012";
for (int i =0; i < user_list.size(); i++) {
s +="[" + user_list.get(i) +"]\015\012";
}
s +="--------------------";
return s;
}
}
public static void main(String[] args)throws IOException {
new Server();//启动服务端
}
}
八、文件传输
客户端向服务器端传送文件,服务端可获取文件名用于保存,获取文件大小计算传输进度,比较简单,直接贴代码。
客户端代码:
package sock;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;
/**
* 客户端
*/
public class Client extends Socket{
private static final String SERVER_IP ="127.0.0.1";
private static final int SERVER_PORT =2013;
private Socket client;
private FileInputStream fis;
private DataOutputStream dos;
public Client(){
try {
try {
client =new Socket(SERVER_IP, SERVER_PORT);
//向服务端传送文件
File file =new File("c:/test.doc");
fis =new FileInputStream(file);
dos =new DataOutputStream(client.getOutputStream());
//文件名和长度
dos.writeUTF(file.getName());
dos.flush();
dos.writeLong(file.length());
dos.flush();
//传输文件
byte[] sendBytes =new byte[1024];
int length =0;
while((length = fis.read(sendBytes,0, sendBytes.length)) >0){
dos.write(sendBytes,0, length);
dos.flush();
}
}catch (Exception e) {
e.printStackTrace();
}finally{
if(fis !=null)
fis.close();
if(dos !=null)
dos.close();
client.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception {
new Client();
}
}
服务器端代码:
package sock;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器
*/
public class Server extends ServerSocket{
private static final int PORT =2013;
private ServerSocket server;
private Socket client;
private DataInputStream dis;
private FileOutputStream fos;
public Server()throws Exception{
try {
try {
server =new ServerSocket(PORT);
while(true){
client = server.accept();
dis =new DataInputStream(client.getInputStream());
//文件名和长度
String fileName = dis.readUTF();
long fileLength = dis.readLong();
fos =new FileOutputStream(new File("d:/" + fileName));
byte[] sendBytes =new byte[1024];
int transLen =0;
System.out.println("----开始接收文件<" + fileName +">,文件大小为<" + fileLength +">----");
while(true){
int read =0;
read = dis.read(sendBytes);
if(read == -1)
break;
transLen += read;
System.out.println("接收文件进度" +100 * transLen/fileLength +"%...");
fos.write(sendBytes,0, read);
fos.flush();
}
System.out.println("----接收文件<" + fileName +">成功-------");
client.close();
}
}catch (Exception e) {
e.printStackTrace();
}finally {
if(dis !=null)
dis.close();
if(fos !=null)
fos.close();
server.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args)throws Exception {
new Server();
}
}
转自http://my.oschina.net/leejun2005/blog/104955
发表评论
文章已被作者锁定,不允许评论。
-
ReentrantLock与Condition
2017-03-17 14:25 535多线程和并发性并不是什么新内容,但是 Java 语言设计中的创 ... -
java linux监控
2017-03-13 17:49 516http://agapple.iteye.com/blog/1 ... -
transient和volatile两个关键字
2017-02-16 09:47 581transient和volatile两个关 ... -
java 锁机制
2016-12-09 13:43 483一段synchronized的代码被 ... -
java 正则表达式
2016-12-02 10:28 526众所周知,在程序开发中,难免会遇到需要匹配、查找、替换、判断字 ... -
java ClassNotFoundException和NoClassDefFoundException的差别
2016-08-17 19:47 923首先从名字上可以看出一类是异常,一类属于错误。异常可以通过异常 ... -
ThreadLocal
2016-07-19 11:10 348ThreadLocal是什么 Thre ... -
java CAS
2016-07-10 14:55 360cas 乐观锁每次不锁定整个线程,在操作之前进行判断。悲观锁独 ... -
concurrenthashmap
2016-07-10 11:11 431hash table虽然性能上不如 ... -
java 线程池的使用
2016-07-10 09:52 3821. 引言 合理利用线程池能够带来三个好处。第一:降低资源消 ... -
java.util.concurrent
2016-07-03 16:24 417我们都知道,在JDK1.5之 ... -
JVM 配置 以及垃圾收集器的选择
2016-04-15 12:36 742JVM监控的关键指标说明: a) FGC的环比增加次数。Zab ... -
jvm实时监控工具
2016-04-09 09:35 493 -
哈希 、一致性哈希、余数式哈希
2016-04-07 16:10 880什么是Hash Hash,一 ... -
jvm dump 相关
2016-03-22 17:22 688http://www.cnblogs.com/edwardla ... -
深入剖析volatile关键字
2016-03-21 16:02 567深入剖析volatile关键字 ... -
java线程安全问题之静态变量、实例变量、局部变量
2016-03-08 12:52 583java多线程编程中,存在很多线程安全问题,至于什么是线程安全 ... -
有状态的bean和无状态的bean的区别
2016-03-08 11:23 1553有状态会话bean :每个用户有自己特有的一个实例,在用户的生 ... -
Java nio详解
2016-01-20 16:30 570http://www.ibm.com/developerwor ... -
java 不定长数组
2015-11-24 15:00 810在调用某个方法时,若是方法的参数个数事先无法确定该如何处理 ...
相关推荐
Java网络编程是软件开发中的重要组成部分,特别是在分布式系统和互联网应用中不可或缺。本文将深入探讨Java网络编程的核心概念、关键技术和实用技巧。 首先,我们来理解Java中的Socket编程。Socket在计算机网络中...
Java网络编程是编程领域中的重要组成部分,它允许程序在不同的设备之间交换信息。本文将深入讲解Java中的网络编程基础知识,帮助初学者理解并掌握这一技术。 首先,理解网络编程的本质至关重要。网络编程涉及两个或...
Java网络编程是构建分布式应用程序的关键技术,而Java Socket编程则是其核心部分,允许两台计算机通过网络进行双向通信。在Java中,Socket是基于TCP/IP协议的,提供了可靠的、面向连接的数据传输服务。 首先,理解...
总结起来,这份资料包涵盖了Java网络编程的核心部分:基础的Socket编程,深入的TCP协议理解,以及高级的事务管理机制。通过学习这些内容,开发者能够熟练地构建和优化网络应用程序,处理并发和数据传输问题,同时...
Java网络编程是计算机科学中的一个重要领域,特别是在分布式系统和服务器端开发中不可或缺。这个实验报告主要涉及了两个关键概念:I/O操作和线程管理,同时包含了一个基本的聊天室代码实现,这为我们提供了理解Java...
总结来说,这个"java网络编程基础"示例涵盖了如何创建基本的服务器和客户端应用程序,以及如何通过TCP连接进行数据交换。通过分析和学习这两个文件,初学者可以了解Java网络编程的基本概念,为进一步的网络应用开发...
总结来说,Java网络编程和分布式计算是构建现代网络应用的基础技术,它们允许开发者创建出可以协同工作的网络应用程序,并将这些程序部署在分布式环境中。掌握这些技术,能够使程序员充分利用Java语言的跨平台优势,...
总结来说,Java网络编程与分布式计算涉及的内容广泛,包括网络通信的基本原理,Java提供的相关API,以及分布式系统的设计和实现。掌握这些知识,对于成为专业的Java开发人员,尤其是从事云计算和大数据领域的开发者...
Java Socket 编程总结 Java Socket 编程是Java语言中用于网络编程的主要技术之一。它允许开发者创建网络应用程序,通过Socket实现客户机/服务器结构的通信。在Java中,Socket编程主要是基于TCP/IP协议的网络编程。 ...
### Java网络编程精讲知识点概览 #### 一、Java网络编程基础 1. **网络编程概念**: - 网络编程是指利用计算机网络技术进行数据交换和资源共享的一种编程方式。 - Java提供了强大的网络编程支持,使得开发者能够...
总结,本Java网络编程聊天程序报告详细阐述了一个基于Java的聊天程序的设计与实现,涵盖了系统的需求分析、功能设计、特点、架构以及权限管理等方面。这样的系统为用户提供了一个安全、高效的在线交流平台,充分体现...
《Java网络高级编程》是一本专注于Java网络编程的教材,涵盖了从基础到高级的各种网络编程技术和概念。根据描述,本书共分为11章,每一章都详细介绍了网络编程中的不同知识点。以下是对本书内容的详细介绍: 在第1...
在本项目中,"Java网络编程 五子棋 课程设计"是一个综合性的学习任务,旨在让学生通过实际操作深入理解网络编程和游戏开发的基本概念。这个项目涵盖了多个关键知识点,包括Java编程语言、网络通信协议、多线程、游戏...
总结一下,本教程主要介绍了Java网络编程的基础知识,包括使用`ServerSocket`创建服务器,`Socket`建立客户端连接,以及如何通过输入输出流进行数据交换。同时,也提到了使用Swing创建简单GUI的方法。继续深入实践,...
本实验主要涉及Java网络编程的基础知识,包括使用InetAddress类获取主机的IP地址和主机名称,使用Socket和ServerSocket类实现C/S通信。这些知识点对于Java网络编程非常重要,对于后续的学习和开发具有重要的参考价值...
总结来说,Java网络编程中的端口扫描器通过Socket类实现了对目标IP的端口探测,结合多线程技术提高了扫描效率。然而,使用此类工具时,我们必须意识到可能涉及的法律和道德问题,合理合法地使用这些技术。
总结来说,Java网络编程包括了对UDP和TCP协议的支持,通过Socket API可以实现客户端和服务器之间的通信。无论是简单聊天软件还是复杂的分布式系统,理解并熟练掌握这些基础知识都是至关重要的。