socket_tutorial笔记(上)

目录:

1. Tutorial tips

2. Socket basics

3. An undercover socket

4. A simple example

5. A multithreaded example

6. A pooled example

7. Sockets in real life

8. Summary

9. Appendix

 

 

section 2.socket basics开始:

socket 涉及的内容既包括底层的细节也包括抽象层中我们常用到的东西。

1 OSI的著名的七层协议模型。物理、数据、网络、传输、会话、表示、应用

2 socketsesssion layer。(*the role sockets play: socket 是一个面向高层的用于通信的接口,把具体的实现和数据流的传输等底层运作对高层屏蔽了。就像电话传输声音一样。

3 what sockets really are? 布鲁斯 埃克尔在thinking in java中的描述:The socket is the software abstraction used to represent the "terminals" of a connection between two machines. For a given connection, there's a socket on each machine, and you can imagine a hypothetical "cable" running between the two machines with each end of the "cable" plugged into a socket. Of course, the physical hardware and cabling between machines is completely unknown. The whole point of the abstraction is that we don't have to know more than is necessary.

In a nutshell, socket就是连接在两台电脑上的一个communicate channel. 你传送数据到别的电脑上,每经过一个TCP/IP栈,这个栈就给你的数据上加个头,这个头用于标识正确的方向(?)。好在java把这些都屏蔽了,by providing the data to your code on streams

4 socket的种类:

* TCP sockets (implemented by the Socket class)

* UDP sockets (implemented by the DatagramSocket class)

tcpudp作用一样、但是做法不一样。两者都是接收传输协议包,并把它们的内容传给表示层。tcp 把消息分割成很多packets(datagrams)并且将它们按正确顺序发送到接收端,tcp还负责传输的要求重传丢失的数据包;而udp是按无序方式发送数据包,并且也没有retransmit requesting的功能,就需要让编程者来考虑实现这些细节。

大家比较倾向于使用TCP sockets

 

 

section 3: An Undercover Socket

1 介绍:java platform提供了java.net 包来实现socket,以下介绍三个包中比较常用的类:

* URLConnection

* Socket

* ServerSocket

2 使用简易的socket

URLConnection 是一个抽象的基类,实现了它的所有子类都是用来创建一个应用与URL之间的communication link.它对获得web server上的文档尤其有用,但是也可以连接所有有URL路径的其他资源。

Connecting to a URL 包括以下几步:

* Create the URLConnection

* Configure it using various setter methods

* Connect to the URL

* Interact with it using various getter methods

 

 

*之下是一个用URLConnectionn类的例子:

 

 

The URLClient class

---------------------------------------------

import java.io.*;

import java.net.*;

public class URLClient {

    protected URLConnection connection;

    public static void main(String[] args) {

    }

    public String getDocumentAt(String urlString) {

    }

}

---------------------------------------------------------

一个main()函数和一个getDocumentAt函数,函数定义及解释见下:

main():

public static void main(String[] args) {

    URLClient client = new URLClient();

    String yahoo = client.getDocumentAt("http://www.yahoo.com");

    System.out.println(yahoo);

}

-----------------------------------------------------

getDocumentAt():

public String getDocumentAt(String urlString) {

    StringBuffer document = new StringBuffer();

    try {

        URL url = new URL(urlString);//定义一个url

        URLConnection conn = url.openConnection();//连接url,这是URLConnection真正的作用

        BufferedReader reader = new BufferedReader(new

            InputStreamReader(conn.getInputStream()));//读入数据,Reader类有时间一定要看一下

        String line = null;

        while ((line = reader.readLine()) != null)

        document.append(line + "/n");

        reader.close();

    } catch (MalformedURLException e) {//如果URL是错的,就会抛出MalformedURLException

        System.out.println("Unable to connect to URL: " + urlString);

    } catch (IOException e) {

        System.out.println("IOException when connecting to URL: " + urlString);

    }

    return document.toString();

}

----------------------------------------------

例子的总结,在上边的例子中,URLConnection 使用了一个socket来读取指定url(只是定向到ip)中的数据。我们不用关心细节。

再来看一下如何创建和使用一个URLConnection

1. Instantiate a URL with a valid URL String of the resource you're connecting to (throws a MalformedURLException if there's a problem).

2. Open a connection on that URL.

3. Wrap the InputStream for that connection in a BufferedReader so you can read lines.

4. Read the document using your BufferedReader.

5. Close your BufferedReader.

*

 

 

section 4: a simple example

 

 

背景:

以下的例子演示了如何在java中使用SocketServerSocket。客户使用Socket连接服务器,服务器用ServerSocketport 3000上监听客户请求。客户要求获得服务器中c盘上的文件的内容。

 

 

Creating the RemoteFileClient class

-----------------------------------------------------------------

import java.io.*;

import java.net.*;

public class RemoteFileClient {

    protected String hostIp;

    protected int hostPort;

    protected BufferedReader socketReader;

    protected PrintWriter socketWriter;

    public RemoteFileClient(String aHostIp, int aHostPort) {

        hostIp = aHostIp;

        hostPort = aHostPort;

    }

    public static void main(String[] args) {

    }

    public void setUpConnection() {

    }

    public String getFile(String fileNameToGet) {

    }

    public void tearDownConnection() {

    }

}

----------------------------------------------

main()

public static void main(String[] args) {

    RemoteFileClient remoteFileClient = new RemoteFileClient("127.0.0.1", 3000);

    remoteFileClient.setUpConnection();//功能函数1,连接远程服务器

    String fileContents =

    remoteFileClient.getFile("C://WINNT//Temp//RemoteFile.txt");//功能函数2,获取内容

    remoteFileClient.tearDownConnection();//功能函数3,结束连接

    System.out.println(fileContents);

}

----------------------------------------------

setUpConnectin()

public void setUpConnection() {

    try {

        Socket client = new Socket(hostIp, hostPort);//重点!,用一个socket连接了远程服务器

        socketReader = new BufferedReader(

        new InputStreamReader(client.getInputStream()));//还是建立读数据通道

        socketWriter = new PrintWriter(client.getOutputStream());//写数据通道

    } catch (UnknownHostException e) {

    System.out.println("Error setting up socket connection: unknown host at " + hostIp +

        ":" + hostPort);

    } catch (IOException e) {

        System.out.println("Error setting up socket connection: " + e);

    }

}

Remember that our client and server simply pass bytes back and forth.

---------------------------------------------

getFile() talking to the host

public String getFile(String fileNameToGet) {

    StringBuffer fileLines = new StringBuffer();

    try {

        socketWriter.println(fileNameToGet);

        //把想要的文件名传给服务器,当然要先和那边定好这是在传什么

        socketWriter.flush();//flush()用来强制将数据发送到服务器而不关闭socket.

        String line = null;

        while ((line = socketReader.readLine()) != null)//读那个文件的内容

            fileLines.append(line + "/n");

    } catch (IOException e) {

        System.out.println("Error reading from file: " + fileNameToGet);

    }

    return fileLines.toString();

}

--------------------------------------

关闭连接

public void tearDownConnection() {

    try {

        socketWriter.close();

        socketReader.close();

    } catch (IOException e) {

        System.out.println("Error tearing down socket connection: " + e);

    }

}

--------------------------------------

客户端步骤:

1. Instantiate a Socket with the IP address and port of the machine you're connecting to

(throws an Exception if there's a problem).

2. Get the streams on that Socket for reading and writing.

3. Wrap the streams in instances of BufferedReader/PrintWriter, if that makes

things easier.

4. Read from and write to the Socket.

5. Close your open streams.

-----------------------------------------------------------------

Creating the RemoteFileServer class

 

 

import java.io.*;

import java.net.*;

public class RemoteFileServer {

    protected int listenPort = 3000;

    public static void main(String[] args) {

    }

    public void acceptConnections() {

    }

    public void handleConnection(Socket incomingConnection) {

    }

}

 

 

-------------------------------------------

Main()

public static void main(String[] args) {

    RemoteFileServer server = new RemoteFileServer();

    server.acceptConnections();

}

-------------------------------------------

accept connection

public void acceptConnections() {

    try {

        ServerSocket server = new ServerSocket(listenPort);//这是重点,参数是端口号

        Socket incomingConnection = null;

        while (true) {//无限循环

            incomingConnection = server.accept();//accept函数阻塞直到连接请求到达

//可以对accept设置时间上限 来在超时时调用setSoTimeOut()引发一个IOException

            handleConnection(incomingConnection);

        }

    } catch (BindException e) {

        System.out.println("Unable to bind to port " + listenPort);

    } catch (IOException e) {

        System.out.println("Unable to instantiate a ServerSocket on port: " + listenPort);

    }

}

---------------------------------------------

Handling Connection

public void handleConnection(Socket incomingConnection) {

    try {

        OutputStream outputToSocket = incomingConnection.getOutputStream();

        InputStream inputFromSocket = incomingConnection.getInputStream();

        BufferedReader streamReader = new BufferedReader(new

            InputStreamReader(inputFromSocket));

        FileReader fileReader = new FileReader(new File(streamReader.readLine()));

        BufferedReader bufferedFileReader = new BufferedReader(fileReader);

        PrintWriter streamWriter = new

            PrintWriter(incomingConnection.getOutputStream());

        String line = null;

        while ((line = bufferedFileReader.readLine()) != null) {

            streamWriter.println(line);

        }

        fileReader.close();

        streamWriter.close();

        streamReader.close();

    } catch (Exception e) {

        System.out.println("Error handling a client: " + e);

    }

}

 

 

---------------------------------------------

 

 

1. Instantiate a ServerSocket with a port on which you want it to listen for incoming

client connections (throws an Exception if there's a problem).

2. Call accept() on the ServerSocket to block while waiting for connection.

3. Get the streams on that underlying Socket for reading and writing.

4. Wrap the streams as necessary to simplify your life.

5. Read from and write to the Socket.

6. Close your open streams (and remember, never close your Reader before your Writer).

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值