TCP和UDP套接字编程 (java实现)

在了解网络编程之前,我们先了解一下什么叫套接字

套接字即指同一台主机内应用层和运输层之间的接口

由于这个套接字是建立在网络上建立网络应用的可编程接口

因此也将套接字称为应用程序和网络之间的应用程序编程接口!

关于TCP和UDP这里就不作太多介绍了,我们知道TCP是面向连接的,UDP是不面向连接的,TCP可靠,UDP不可靠即可!
我们来设计一个应用来示范一下,流程:

  1. 客户机从键盘读取一行字符串,并通过套接字发送到服务器。
  2. 服务器从连接的套接字获取这行字符串,并对其进行修改(将小写转为大写),最后再发回客户端。
  3. 客户机读取到服务器发送的修改后的字符串,并输出到屏幕。

不说太多了,直接上代码:

TCP套接字编程:

客户端:

package TCP套接字编程;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {
    public static void main(String[] args) throws UnknownHostException,
            IOException {
        // 创建两个String类型的字符串用来接收和发送字符
        String sentence;
        String modifiedSentence;

        // 创建输入流,用来接收键盘输入
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                System.in));

        // 创建一个Scoket型的clientScoket用来发起服务器和客户机之间的连接
        String postname = "169.264.187.20";// 客户端ip地址(请用自己电脑的ip地址代替)
        Socket clientSocket = new Socket(postname, 6789);

        // 创建向服务器发送信息的输出流
        DataOutputStream outToServer = new DataOutputStream(
                clientSocket.getOutputStream());

        // 创建输入流,用来接收来自服务器的字节流
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));

        // 读取要发送的数据
        sentence = inFromUser.readLine();

        // 向服务器发送数据
        outToServer.writeBytes(sentence + ‘\n‘);

        // 获取从服务器接收的数据
        modifiedSentence = inFromServer.readLine();

        // 打印接收数据
        System.out.println("From Server:" + modifiedSentence);

    }

}

服务器端:

package TCP套接字编程;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        // 从客户端接收的字符串,要发送给客户端的字符串
        String clientSentence;
        String serverSentence;

        // 服务器打开6789端口,建立连接
        ServerSocket welcomeSocket = new ServerSocket(6789);

        while (true) {// 服务器的6789端口一直打开

            // 用此连接来获取和发送客户端数据流
            Socket connectionSocket = welcomeSocket.accept();

            // 获取来自客户端的数据流
            BufferedReader inFromClient = new BufferedReader(
                    new InputStreamReader(connectionSocket.getInputStream()));

            // 准备发送更改后的数据流
            DataOutputStream outToClient = new DataOutputStream(
                    connectionSocket.getOutputStream());

            // 读取收到的数据
            clientSentence = inFromClient.readLine();

            // 将读取到的数据都中的小写字母改为大写字母
            serverSentence = clientSentence.toUpperCase() + ‘\n‘;

            // 发送修改后的数据给客户端
            outToClient.writeBytes(serverSentence);

        }
    }
}

UDP套接字编程:

客户端:

package UDP套接字编程;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClient {
    public static void main(String[] args) throws IOException {
        // 读取键盘输入的字节流
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                System.in));

        // 为客户端创造一个传输信息的门,但是并没有像TCP那样建立连接
        DatagramSocket clientSocket = new DatagramSocket();

        // 调用DNS查询,得到主机名对应的IP地址
        InetAddress IPAddress = InetAddress.getByName(null);//null的话得到的是自己的IP地址
        System.out.println(IPAddress);

        // 定义需要发送的字节数组
        byte[] sendData = new byte[1024];// 不能动态开数组。。。

        // 定义需要接收的字节数组
        byte[] receiveData = new byte[1024];

        // 将从键盘接收到的数据先用字符串存起来
        String sentence = inFromUser.readLine();

        // 将字符串转为字节存入sendData
        sendData = sentence.getBytes();

        // 准备发送UDP数据报,里面包含发送内容和目的地址等信息
        DatagramPacket sendPacket = new DatagramPacket(sendData,
                sendData.length, IPAddress, 9878);

        // 用这个门来发送数据报
        clientSocket.send(sendPacket);

        // 准备获取从服务器返回的数据报
        DatagramPacket receivePacket = new DatagramPacket(receiveData,
                receiveData.length);

        // 用这个门来接收服务器发的数据报
        clientSocket.receive(receivePacket);

        // 将获取的数据报转换为String类型
        String modifiedSentence = new String(receivePacket.getData());

        // 打印从服务器收到的内容
        System.out.println("From Server:" + modifiedSentence + ‘\n‘);

        // 关闭这个门
        clientSocket.close();

    }

}

服务器端:

package UDP套接字编程;

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

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

        // 创建一个门,在9878端口
        DatagramSocket serverSocket = new DatagramSocket(9878);

        while (true) {

            // 定义接收数据的字节数组
            byte[] receiveData = new byte[1024];

            // 定义发送数据的字节数组
            byte[] sendData = new byte[1024];

            // 创建UDP数据报对象,准备接收UDP数据报
            DatagramPacket receivePacket = new DatagramPacket(receiveData,
                    receiveData.length);

            // 接收UDP数据报
            serverSocket.receive(receivePacket);

            // 将收到的UDP数据报转换为String字符串
            String sentence = new String(receivePacket.getData());

            // 得到接收到的UDP数据报的源IP地址
            InetAddress IPAddress = receivePacket.getAddress();

            // 得到接收到的UDP数据报的源端口号
            int port = receivePacket.getPort();

            // 小写字母全部变为大写字母
            String capitalized = sentence.toUpperCase();

            // 将字符串转换为字节数组以便发送
            sendData = capitalized.getBytes();

            // 准备发送字节数组,做好封装UDP数据报工作
            DatagramPacket sendPacket = new DatagramPacket(sendData,
                    sendData.length, IPAddress, port);

            // 通过门正式发送UDP数据报
            serverSocket.send(sendPacket);

        }
    }
}

分析:

先运行服务器端代码,这样服务器才能工作:打开相应端口,做好接收数据的准备

然后运行客户端代码,发送数据

服务器工作时,对应端口一直的打开的,随时准备响应客户端的请求

参考书籍:《计算机网络自顶向下方法》

原文地址:https://www.cnblogs.com/yinbiao/p/10160574.html

时间: 2024-08-27 17:42:47

TCP和UDP套接字编程 (java实现)的相关文章

【Python网络编程】利用Python进行TCP、UDP套接字编程

之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接字将该行发送到服务器. 2.服务器从其连接套接字读取一行字符. 3.服务器将该行字符转换成大写. 4.服务器将修改后的字符串(行)通过连接套接字再发回给客户机. 5.客户机从其套接字中读取修改后的行,然后将该行在其标准输出(监视器)上打印出来. [TCP]服务器端代码: import socket

TCP下的套接字编程

1.什么是套接字 应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据.为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口.区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址.使用的传输层协议(TCP或UDP)和使用的端口号.Socket原意是"插座".通过将这3个参数结合起来,

探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

【转】 探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

《网络编程》基本 UDP 套接字编程

在前面文章中介绍了<UDP 协议>和<套接字数据传输>.UDP 协议和 TCP 协议不同,它是一种面向无连接.不可靠的传输层协议.在基于 UDP 套接字编程中,数据传输可用函数 sendto 和 recvfrom.以下是基本 UDP 套接字编程过程: sendto 与 recvfrom 函数 这两个函数的功能类似于 write 和 read 函数,可用无连接的套接字编程.其定义如下: /* 函数功能:发送数据: * 返回值:若成功则返回已发送的字节数,若出错则返回-1: * 函数原

apue和unp的学习之旅10——基本udp套接字编程

使用UDP编写的一些常见的应用程序有:DNS(域名系统),NFS(网络文件系统),SNMP(简单网络管理协议). //---------------------------------1.recvfrom函数和sendto函数---------------------------------- #include <sys/socket.h> ssize_t  recvfrom(int sockfd, void* buff, size_t nbytes, int flags, struct so

linux下的UDP套接字编程

一.相关过程以及知识请详见我的另一篇博客<winsock套接字编程>,这里不再累述. 二.相关代码: server.c:  1 /****************************************                                                                                                    2     > File Name:server.c   3     > A

《网络编程》高级 UDP 套接字编程

概述 UDP 是一个无连接.不可靠的数据报协议,任何可靠传输都需由应用程序提供,例如:超时重传.序列号应答机制,但是它在某些场合使用效率高,方便.它支持广播和多播.有关<基本 UDP 套接字编程>参照该文,这里只是在那个基础上,记录一些在 UDP 编程中容易出现的问题. 辅助数据 辅助数据(也称为控制信息)可通过调用 recvmsg 和 sendmsg 函数使用,这里两个函数的定义可参考文章<高级 I/O>,使用 msghdr 结构体中的 msg_control 和 msg_con

Unix网络编程学习笔记之第8章 基于UDP套接字编程

一. UDP C/S的典型函数调用 UDP没有像TCP那样的连接,客户端直接sendto向某服务器发送数据,服务器端一直recvfrom阻塞,以接收任何客户端发送的数据. 二. sendto和recvfrom函数 int sendto(int sockfd, const void* buff, size_t nbytes, int flag, const struct sockaddr* to, socklen_taddrlen); int recvfrom(int sockfd, void*