<分布式程序设计> 读书笔记二

二 了解socket编程

内部通信方式

2 socket

Socket与文件描述符一样,可以打开///关闭

unix系统中,端口号0-1023预留给rootsuperuser

Socket类型

sock_stream 字节流通信

Socket_dcram 数据报文传输

Socket_ram 对信息传输进行高级控制  java不支持

3 tcp/ip udp/ip通信

数据报通信协议 如:udp无联接协议 

流通信协议 tcp协议面向连接的协议

Udptcp

Udp需要发送本地描述符和接收方地址,数据报不能超过64kb,不能保证接收方按顺序接收,应用场景:客户服务器,程序需要广播,或希望开销较小

Tcp需要建立联接,应用场景:远程登录.FTP,

客户服务器通信

 

使用java进行socket进行编程

SocketdatagramSocket

数据流

inputStream

outputStream

Tcp socket

打开socket

创建数据输入流

创建数据输出流

关闭socket

示例代码如下:

/**

 * Copyright (C) 2015

 * 

 * FileName:TCPEchoClient.java

 *

 * Author:<a href="mailto:[email protected]">Retacn</a>

 *

 * CreateTime: 2015-1-15

 */

// Package Information

package cn.yue.test.net;

 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import java.net.SocketException;

import java.net.UnknownHostException;

 

/**

 * tcp socket 客户端

 * 

 * @version

 * 

 * @Description:

 * 

 * @author <a href="mailto:[email protected]">Retacn</a>

 * 

 * @since 2015-1-15

 * 

 */

public class TCPEchoClient {

 

public static void main(String[] args) throws UnknownHostException, IOException {

// 控制台输入服务器地址,报文和端口

if ((args.length < 2) || (args.length > 3)) {

throw new IllegalArgumentException("(parameter(s):<server> <word> [<port>])");

}

 

String server = args[0];

byte[] data = args[1].getBytes();

int servPort = (args.length == 3) ? Integer.parseInt(args[3]) : 7;

 

// 创建socket

Socket socket = new Socket(server, servPort);

System.out.println("connecting to server ... sending echo string");

 

InputStream in = socket.getInputStream();

OutputStream out = socket.getOutputStream();

// 发送数据

out.write(data);

// 接收数据

int totalBytesRcvd = 0;

int bytesRcvd;

 

while (totalBytesRcvd < data.length) {

if ((bytesRcvd = in.read(data, totalBytesRcvd, data.length - totalBytesRcvd)) == -1) {

throw new SocketException("connection closed prematurely!");

}

totalBytesRcvd += bytesRcvd;

}

System.out.println("received: " + new String(data));

socket.close();

}

}

 

/**

 * Copyright (C) 2015

 * 

 * FileName:TCPEchoServer.java

 *

 * Author:<a href="mailto:[email protected]">Retacn</a>

 *

 * CreateTime: 2015-1-15

 */

// Package Information

package cn.yue.test.net;

 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.SocketAddress;

 

/**

 * tcp socket 服务端程序

 * 

 * @version

 * 

 * @Description:

 * 

 * @author <a href="mailto:[email protected]">Retacn</a>

 * 

 * @since 2015-1-15

 * 

 */

public class TCPEchoServer {

// 用于接收数据的缓冲区

private static final int BUFSIZE = 32;

 

public static void main(String[] args) throws IOException {

// 从控制台接收端口号

if (args.length != 1) {

throw new IllegalArgumentException("parameter(s): <port>");

}

 

int servPort = Integer.parseInt(args[0]);

 

//

ServerSocket serverSocket = new ServerSocket(servPort);

int receiveMsgSize;

byte[] receiveBuf = new byte[BUFSIZE];

// 监听客户端请求

while (true) {

Socket clientSocket = serverSocket.accept();

SocketAddress clientAddress = clientSocket.getRemoteSocketAddress();

System.out.println("handing client as " + clientAddress);

 

InputStream in = clientSocket.getInputStream();

OutputStream out = clientSocket.getOutputStream();

 

while ((receiveMsgSize = in.read(receiveBuf)) != -1) {

// 向客户端写入

out.write(receiveBuf, 0, receiveMsgSize);

}

clientSocket.close();

}

 

}

}

 

 

Udp socket

创建一个datagramSocket实例

使用datagramSocketsend()receive()来发送和接收数据

使用close关闭套接字

示例代码如下:

/**

 * Copyright (C) 2015

 * 

 * FileName:UDPEchoClient.java

 *

 * Author:<a href="mailto:[email protected]">Retacn</a>

 *

 * CreateTime: 2015-1-15

 */

// Package Information

package cn.yue.test.net;

 

import java.io.IOException;

import java.io.InterruptedIOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.SocketException;

import java.net.UnknownHostException;

 

/**

 * udp socket 客户端

 * 

 * @version

 * 

 * @Description:

 * 

 * @author <a href="mailto:[email protected]">Retacn</a>

 * 

 * @since 2015-1-15

 * 

 */

public class UDPEchoClient {

// 设置超时时间

private static final int TIMEOUT = 3000;

// 重复发送次数

private static final int MAXTRIES = 5;

 

public static void main(String[] args) throws IOException {

if ((args.length < 2) || (args.length > 3)) {

throw new IllegalArgumentException("parameter(s) <server> <word> [<port>]");

}

InetAddress serverAddress = InetAddress.getByName(args[0]);

byte[] bytesToSend = args[1].getBytes();

int serverPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;

 

//

DatagramSocket socket = new DatagramSocket(serverPort, serverAddress);

socket.setSoTimeout(TIMEOUT);

 

DatagramPacket sendpacket = new DatagramPacket(bytesToSend, bytesToSend.length, serverAddress, serverPort);

DatagramPacket receivePacket = new DatagramPacket(new byte[bytesToSend.length], bytesToSend.length);

 

// 发送包容易丢失,保持重发

int tries = 0;

boolean receivedResponse = false;

do {

socket.send(sendpacket);

try {

socket.receive(receivePacket);

// 检查数据源

if (!receivePacket.getAddress().equals(serverAddress)) {

throw new IOException("received packet from an unknow source");

}

receivedResponse = true;

} catch (InterruptedIOException e) {

tries += 1;

System.out.println("time out, " + (MAXTRIES - tries) + " more tries...");

}

} while ((!receivedResponse) && (tries < MAXTRIES));

if (receivedResponse) {

System.out.println("received: " + new String(receivePacket.getData()));

} else {

System.out.println("no response -- qiving up.");

}

socket.close();

}

}

 

 

/**

 * Copyright (C) 2015

 * 

 * FileName:UDPEchoServer.java

 *

 * Author:<a href="mailto:[email protected]">Retacn</a>

 *

 * CreateTime: 2015-1-15

 */

// Package Information

package cn.yue.test.net;

 

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

 

/**

 * udp socket 服务器端

 * 

 * @version

 * 

 * @Description:

 * 

 * @author <a href="mailto:[email protected]">Retacn</a>

 * 

 * @since 2015-1-15

 * 

 */

public class UDPEchoServer {

private static final int ECHOMAX = 255;

 

public static void main(String[] args) throws IOException {

// 控制台输入端口号

if (args.length != 1) {

throw new IllegalArgumentException("parameter(s) <port>");

}

int serverPort = Integer.parseInt(args[0]);

DatagramSocket socket = new DatagramSocket(serverPort);

DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);

 

while (true) {

socket.receive(packet);

System.out.println("hading client an " + packet.getAddress() + " on port " + packet.getPort());

socket.send(packet);

packet.setLength(ECHOMAX);

}

}

}

 

 

 

 

 

多点传送socket

MulticastSocket 此类应用于客户端,用监听服务器广播到多个客户的包

使用多点传送ip要使用基于upd协议

6 greetings服务器实例

服务器程序

客户程序

以上两个程序同5所示代码

解析internate地址 

getName  //取得机器的字符名

getIp  //取得机器的ip地址

nsLookUp //根据主机名找ip,反之也可

IPtoName //ip地址转换

你可能感兴趣的:(<分布式程序设计> 读书笔记二)