java socket编程基础

一、传输协议UDP和TCP

TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。

UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的

比较:

1、UDP的传输数据有大小限制,且每个被传输是数据报限定在64kb之内。

2、UDP传输速率快,但是不可靠,TCP相反。

二、Socket编程

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。一个Socket由一个IP地址和一个端口号唯一确定。在java开发环境下,Socket编程主要指基于TCP/IP协议的编程。

创建socket:

1、创建socket:

其构造方法有:

Socket(InetAddress address, int port);

Socket(InetAddress address, int port, boolean stream);

Socket(String host, int prot);

Socket(String host, int prot, boolean stream);

Socket(SocketImpl impl)

Socket(String host, int port, InetAddress localAddr, int localPort)

Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

ServerSocket(int port);

ServerSocket(int port, int backlog);

ServerSocket(int port, int backlog, InetAddress bindAddr)

其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可 以用来创建Socket。count则表示服务端所能支持的最大连接数。

三、通信的基本步骤:

服务器端:

1. 在服务器,用一个端口来实例化一个 ServerSocket对象。此时,服务器就可以这个端口时刻监听从客户端发来的连接请求。
2.调用ServerSocket的accept方法,开始监听连接从端口上发来的连接请求。   
3.利用accept方法返回的客户端的Socket对象,进行读写IO的操作
4.通讯完成后,关闭打开的流和Socket对象。

Demo:必须先启服务

package com.xuzengqiang.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

@SuppressWarnings("all")
public class Server {

	private static Integer port=8060;
	
	public static void run() throws Exception {
		BufferedReader read = null;
		PrintWriter out = null;
		ServerSocket server=new ServerSocket(port);
		System.out.println("服务端启动............");
		
		//一直处于阻塞状态,直到客户端连接
		Socket socket=server.accept();
		System.out.println("客户端与服务器建立连接!");

		read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
		
		while(true){
			Scanner input = new Scanner(System.in);
			
			//接收客户端发送的数据
			String message=read.readLine();
			System.out.println(message);
			//如果客户端发送的数据为"bye!".终止连接
			if("bye!".equals(message)){
				break;
			}
			out.println("管理员:" + input.nextLine());
		}
		
		out.close();
		read.close();
		socket.close();
		server.close();
	}

	public static void main(String[] args) {
		try {
			run();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

客户端:

1.用服务器的IP地址和端口号实例化Socket对象。
2.调用connect方法,连接到服务器上。
3.将发送到服务器的IO流填充到IO对象里,比如BufferedReader/PrintWriter。
4.利用Socket提供的getInputStream和getOutputStream方法,通过IO流对象,向服务器发送数据流。
5. 通讯完成后,关闭打开的IO对象和Socket。

package com.xuzengqiang.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

@SuppressWarnings("all")
public class Client {

	private static InetAddress ipAddress;
	private static Integer port = 8060;

	// 获取本机IP地址
	static {
		try {
			ipAddress = InetAddress.getByName("localhost");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

	public static void start() throws Exception {
		Socket socket = null;
		BufferedReader read = null;
		PrintWriter out = null;

		socket = new Socket(ipAddress, port);
		read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

		while (true) {
			// 利用PrintWriter向服务器发送消息
			Scanner input = new Scanner(System.in);
			out.println("强哥:" + input.nextLine());

			// 利用BufferedReader向服务器接收消息
			String message = read.readLine();
			System.out.println(message);
			if ("bye!".equals(message)) {
				out.println("bye!");
				break;
			}
		}
		
		//关闭流
		out.close();
		read.close();
		socket.close();
	}

	public static void main(String[] args) {
		try {
			start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

多线程通信:上面的程序一个Server只能有一个Client,如果要一个Server可以与多个Client进行通信,可以利用线程。将处理流程放到一个独立的线程中去,然后等待下一个Client连接即可。

Server:服务器端

package com.xuzengqiang.udp.server.more;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

@SuppressWarnings("all")
public class ServerOne {

	private static final Integer port = 8060;

	public static void execute(final Socket socket) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				BufferedReader read = null;
				PrintWriter out = null;
				try {
					read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
					out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
					while (true) {
						Scanner input = new Scanner(System.in);
						// 接收客户端发送的数据
						String message = read.readLine();
						System.out.println(message);
						out.println("管理员:" + input.nextLine());
						out.flush();
						// 如果客户端发送的数据为"bye!".终止连接
						if ("bye!".equals(message)) {
							break;
						}
					}

				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						if (read != null) {
							read.close();
						}
						if (out != null) {
							out.close();
						}
						if (socket != null) {
							socket.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

			}
		}).start();

	}

	public static void main(String[] args) {

		ServerSocket server;
		try {
			server = new ServerSocket(port);
			System.out.println("服务端启动............");
			while (true) {
				// 一直处于阻塞状态,直到客户端连接
				Socket socket = server.accept();
				System.out.println("客户端与服务器建立连接!");
				execute(socket);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}

Client:客户端

package com.xuzengqiang.socket.more;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

@SuppressWarnings("all")
public class ClientTwo {

	private static InetAddress ipAddress;
	private static Integer port = 8060;

	// 获取本机IP地址
	static {
		try {
			ipAddress = InetAddress.getByName("localhost");
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

	public static void start() throws Exception {
		Socket socket = null;
		BufferedReader read = null;
		PrintWriter out = null;

		socket = new Socket(ipAddress, port);
		read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

		while (true) {
			// 利用PrintWriter向服务器发送消息
			Scanner input = new Scanner(System.in);
			out.println("伍岳:" + input.nextLine());

			// 利用BufferedReader向服务器接收消息
			String message = read.readLine();
			System.out.println(message);
			if ("bye!".equals(message)) {
				out.println("bye!");
				break;
			}
		}

		// 关闭流
		out.close();
		read.close();
		socket.close();
	}

	public static void main(String[] args) {
		try {
			start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值