TCP程序设计基础

TCP网络程序设计是指用Socket类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序。两者的功能和编写方法不大一样。服务器端与客户端的交互过程如图所示:
在这里插入图片描述

1. InetAddress类

java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。InetAddress类的常用方法如下表所示:

方法返回值说明
getByName(String host)InetAddress获取与Host相对应的InetAddress对象
getHostAddress()String获取InetAddress对象所包含的IP地址
getHostName()String获取此IP地址的主机名
getLocalHost()InetAddress返回本地主机的InetAddress对象

代码示例如下:

import java.net.*;

public class Address{
	public static void main(String[] args){
		InetAddress ip;
		try{
			ip = InetAddress.getLocalHost();
			String localname = ip.getHostName();
			String localip = ip.getHostAddress();
			System.out.println("本机名:" + localname);
			System.out.println("本机IP地址:" + localip);
		}catch(UnknownHostException e){
			e.printStackTrace();
		}
	}
}

2. ServerSocket类

java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是等待来自网络上的”请求“,它可通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入队列中,然后从中取出一个套接字,与服务器新建的套接字连接起来。若请求连接数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小是50。

ServerSocket类的构造方法有如下几种:

  • ServerSocket():创建非绑定服务器套接字。
  • ServerSocket(int port):创建绑定到特定端口的服务器套接字。
  • ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口号上
  • ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个IP地址的情况,用户可以明确规定ServerSocket在哪块网卡或哪个IP地址上等待客户的连接请求。

ServerSocket类常用的方法如下表所示:

方法返回值说明
accept()Socket等待客户机的连接。若连接,则创建一个套接字
isBound()boolean判断ServerSocket的绑定状态
getInetAddressInetAddress返回此服务器套接字的本地地址
isClosed()boolean返回服务器套接字的关闭状态
close()void关闭服务器套接字
bind(SocketAddress endpointvoid将ServerSocket绑定到特定地址(IP地址和端口号)
getInetAddressint返回服务器套接字等待的端口号

调用ServerSocket类的accept()方法,会返回一个和客户端Socket对象相连接的Socket对象。服务器端的Socket对象使用getOutputStream()方法获得的输出流,将指向客户端Socket对象使用getInputStream()方法获得的那个输出流。也就是说,当服务器向输出流写入信息时,客户端通过相应的输入流就能读取,反之亦然。

accept()方法会阻滞线程的继续执行,直到接收到客户的呼叫。如果没有客户呼叫服务器,那么System.out.println(“连接中”)语句将不会执行。

yu = server.accept();
System.out.println("连接中")

3. TCP网络程序

明白了TCP程序工作的过程,就可以编写TCP服务器程序了。在网络编程中如果只要求客户机向服务器发送消息,不要求服务器向客户机发送消息,称为单向通信。客户机套接字和服务器套接字连接成功后,客户机通过输出流发送数据,服务器则通过输入流接收数据。下面是简单的单向通信的实例。

TCP服务器程序:

import java.io.*;
import java.net.*;

public class MyTcp{
	private BufferedReader reader;
	private ServerSocket server;
	private Socket socket;
	void getserver(){
		try{
			server = new ServerSocket(8998);
			System.out.println("服务器套接字已经创建成功")
			while(true){
				System.out.println("等待客户机的连接");
				socket = server.accept();
				reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				getClientMessage();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	private void getClientMessage(){
		try{
			while(true){
				System.out.println("客户机:"+reader.readLine();)
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		try{
			if(reader != null){
				reader.close()
			}
			if(reader != null){
				socket.close()
			}
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public static void main(String[] args){
		MyTcp tcp = new MyTcp();
		tcp.getserver();
	}
}

客户端程序:

package com.lzw;

public class MyClien extends JFrame{
	private PrintWriter writer;
	Socket socket;
	private JTextArea ta = new JTextArea();
	private JTextField tf = new JTextField();
	Container cc;
	
	public MyClien(String title){
		super(title); //调用父类的构造方法
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		cc = this.getContentPane();
		final JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
		getContentPane().add(scrollPane, BorderLayout.CENTER);
		scrollPane.setViewportView(ta);
		cc.add(tf,"South"); //将文本框放在窗体的下部
		tf.addActionListener(new ActionLisener(){
			//绑定事件
			public void actionPerformed(ActionEvent e){
				writer.println(tf.getText()); //将文本框中的信息写入流
				ta.append(tf.getText() + '\n'); //将文本框中的信息显示在文本域
				ta.setSelectionEnd(ta.getText().length());
				tf.setText(""); //将文本框清空
			}
		});
	}
	private void connect(){
		ta.append("尝试连接\n");
		try{
			socket = new Socket("127.0.0.1", 8998);
			writer = new PrintWriter(socket.getOutputStream(),true);
			ta.append("完成连接\n")
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public static void main(String[] args){
		MyClien = new MyClien("向服务器送数据");
		clien.setSize(200,200); //设置窗体大小
		clien.setVisible(true); //将窗体显示
		clien.connect(); //调用连接方法
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值