Socket(TCP和UDP)详解

使用基于TCP协议的Socket
一个客户端要发起一次通信,首先必须知道运行服务器端的主机IP地址。然后由网络基础设施利用目标地址,将客户端发送的信息传递到正确的主机上,在Java中,地址可以由一个字符串来定义,这个字符串可以使数字型的地址(比如192.168.1.1),也可以是主机名(example.com)。
在Java当中InetAddress类代表了一个网络目标地址,包括主机名和数字类型的地址信息。

1. 基于TCP协议操作Socket的API:
ServerSocket:这个类是实现了一个服务器端的Socket,利用这个类可以监听来自网络的请求。

a) 创建ServerSocket的方法:
ServerSocket(Int localPort)
ServerSocket(int localport,int queueLimit)
ServerSocket(int localport,int queueLimit,InetAddress localAddr)
创建一个ServerSocket必须指定一个端口,以便客户端能够向该端口号发送连接请求。端口的有效范围是0-65535

b) ServerSocket操作
Socket accept()
void close
accept()方法为下一个传入的连接请求创建Socket实例,并将已成功连接的Socket实例返回给服务器套接字,如果没有连接请求,accept()方法将阻塞等待;
close方法用于关闭套接字

Socket

a) 创建Socket的方法:
Socket(InetAddress remoteAddress,int remotePort)

利用Socket的构造函数,可以创建一个TCP套接字后,先连接到指定的远程地址和端口号。

b) 操作Socket的方法
InputStream getInputStream()
OutputStream getOutputStream()
void close()

image

使用基于UDP的Socket

a) 创建DatagramPacket
DatagramSocket(byte [] data,int offset,int length,InetAddress remoteAddr,int remotePort)
该构造函数创建一个数据报文对象,数据包含在第一个参数当中

b) 创建DatagramSocket创建
DatagramSocket(int localPort)
以上构造函数将创建一个UDP套接字;

c) DatagramSocket:发送和接受
void send(DatagramPacket packet)
void receive(DatagramPacket packet)
send()方法用来发送DatagramPacket实例。一旦创建连接,数据报将发送到该套接字所连接的地址;
receive()方法将阻塞等待,知道接收到数据报文,并将报文中的数据复制到指定的DatagramPacket实例中

服务器端Socket:Socket.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package mars.socket;
 
import java.net.DatagramPacket;
import java.net.DatagramSocket;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
/**
  * 服务器端Socket
  * @author Administrator
  *
  */
public class SocketActivity extends Activity {
     /** Called when the activity is first created. */
     private Button startButton = null ;
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
         startButton = (Button)findViewById(R.id.startListener);
         startButton.setOnClickListener( new StartSocketListener());
     }
     
     class StartSocketListener implements OnClickListener{
 
         @Override
         public void onClick(View v) {
             new ServerThread().start();
         }
         
     }
     
     class ServerThread extends Thread{
         /**
          * 基于TCP的Socket
          */
         /*public void run(){
             //声明一个ServerSocket对象
             ServerSocket serverSocket = null;
             try {
                 //创建一个ServerSocket对象,并让这个Socket在4567端口监听
                 serverSocket = new ServerSocket(4567);
                 //调用ServerSocket的accept()方法,接受客户端所发送的请求
                 Socket socket = serverSocket.accept();
                 //从Socket当中得到InputStream对象
                 InputStream inputStream = socket.getInputStream();
                 byte buffer [] = new byte[1024*4];
                 int temp = 0;
                 //从InputStream当中读取客户端所发送的数据
                 while((temp = inputStream.read(buffer)) != -1){
                     System.out.println(new String(buffer,0,temp));
                 }
             } catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
             finally{
                 try {
                     serverSocket.close();
                 } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }
         
         }*/
         /**
          * 基于UDP的Socket
          */
         public void run(){
             try {
                 //创建一个DatagramSocket对象,并指定监听的端口号
                 DatagramSocket socket = new DatagramSocket( 4567 );
                 byte data [] = new byte [ 1024 ];
                 //创建一个空的DatagramPacket对象
                 DatagramPacket packet = new DatagramPacket(data,data.length);
                 //使用receive方法接收客户端所发送的数据
                 socket.receive(packet);
                 String result = new String(packet.getData(),packet.getOffset(),packet.getLength());
                 System.out.println( "result--->" + result);
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
     }
}

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="mars.socket"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".SocketActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="4" />

	<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
	<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest> 

TCPClient.java

package mars;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;

public class TCPClient {
	public static void main(String[] args) {
		try {
			//创建一个Socket对象,指定服务器端的IP地址和端口号
			Socket socket = new Socket("192.168.1.104",4567);
			//使用InputStream读取硬盘上的文件
			InputStream inputStream = new FileInputStream("f://file/words.txt");
			//从Socket当中得到OutputStream
			OutputStream outputStream = socket.getOutputStream();
			byte buffer [] = new byte[4*1024];
			int temp = 0 ;
			//将InputStream当中的数据取出,并写入到OutputStream当中
			while((temp = inputStream.read(buffer)) != -1){
				outputStream.write(buffer, 0, temp);
			}
			outputStream.flush();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

UDPClient.java:

package mars;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClient {
	public static void main(String[] args) {
		try {
			//首先创建一个DatagramSocket对象
			DatagramSocket socket = new DatagramSocket(4567);
			//创建一个InetAddree
			InetAddress serverAddress = InetAddress.getByName("192.168.1.104");
			String str = "hello";
			byte data [] = str.getBytes();
			//创建一个DatagramPacket对象,并指定要讲这个数据包发送到网络当中的哪个地址,以及端口号
			DatagramPacket packet = new DatagramPacket(data,data.length,serverAddress,4567);
			//调用socket对象的send方法,发送数据
			socket.send(packet);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值