Socket编程实验报告

                      实验报告

实验一 Socket编程

一、实验目的

  通过socket程序的编写、调试,掌握socket编程的基本方法,了解客户端与服务器端的特点,掌握并熟悉运用socket类与ServerSocket类。

二、实验内容

①学习socket编程使用的类和接口,着重掌握基于TCP协议的socket。

②编写服务器端的应用程序

③编写客户端的应用程序

④实现服务器端与客户端的交互

三、实验代码

1.服务器端程序

过程:在端口5000上创建一个等待连接的ServerSocket对象server:server=new ServerSocket(5000);接着调用server对象的accept()方法等待某客户程序发出连接请求。该方法一直阻塞直到有客户连接到带端口。一旦有客户发送正确请求,则连接成功,accept()方法返回一个Socket对象,于是得到了一个新的用于通信的Socket对象,通信链路建立成功。然后利用Socket类提供的方法创建Socket对象的输入流和输出流。此后即于客户端进行通信,直到客户端断开连接即关闭各个流结束通信。

代码如下:

import java.net.*;

import java.io.*;

 class  aa

{

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

       {

              ServerSocket server=null;

              Socket socket=null;

              InputStream is=null;

              OutputStream os=null;

              DataInputStream in=null;

              PrintStream out=null;

              try

                {  //在端口5000注册服务

                   server=new ServerSocket(5000);

                   socket =server.accept();//侦听连接请求,等待连接

                   System.out.println("**********************服务器端界面*************************");

                   System.out.println("与客户端连接成功!");

                   System.out.println("");

                   System.out.println("对话内容为:");

                   System.out.println("");

                   System.out.println("等待客户发送信息.....");

             //获取对应的Socket的输入/输出流

                   is=socket.getInputStream();

          os=socket.getOutputStream();

             //建立数据流

                   in= new DataInputStream(is);

                   out =new PrintStream(os);//表示向对方输出

                     out.println("Welcome!");//表示向对方输出

                   String str=in.readLine();//逐行读取

                   do

                   {

                     System.out.println("客户端说:"+ str);

                     str=in.readLine();

                   }while(str.trim().equals("BYE")) //如果是“BYE”就退出

                   System.out.println("客户想要离开"); 

                }

                 catch(Exception e)  //捕获程序异常

                 {

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

                  }

                 finally

                 {

                     is.close();//关闭输入流

                       os.close();//关闭输出流

                       in.close();//关闭数据输入流

                       socket.close();//关闭socket

                 }

}

}

2.客户端程序

过程:首先创建一个指向服务器的指定端口号(5000)的Socket对象socket:socket=new Socket("localhost",5000);此时服务器指定为本地计算机,若要在网络中指定服务器,只需要将参数localhost改成相应的服务器名或者IP地址即可。

  然后程序利用Socket类提供的方法创建Socket对象的输入流和输出流。此后即于服务器通信,断开连接即关闭各个流结束通信。

代码如下:

import java.net.*;

import java.io.*;

 class  bb

{

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

       {

              Socket socket=null;

              InputStream is=null;

              OutputStream os=null;

              DataInputStream in=null;

              PrintStream out=null;

              String d=null;

              try

                { //向本地服务器申请链接

          //注意端口号要与服务器保持一致:5000

                   socket=new Socket("localhost",5000);

                   System.out.println("********************客户端界面************************");

                   System.out.println("与服务器连接成功!");

                   System.out.println("");

                   System.out.println("对话内容为:");

                   System.out.println("");

                   System.out.println("请输入信息:");

          //获取对应的Socket的输入/输出流

                   is=socket.getInputStream();

                   os=socket.getOutputStream();

           //建立数据流

                   in= new DataInputStream(is);

                   out=new PrintStream(os);

                   d=in.readLine();

                   System.out.println("服务器说:"+d);

                   byte a[]=new byte[100];

                   System.in.read(a);

                   String b=new String(a,0);

                   b=b.trim();//去点输入的第一个字符前的空格

                   while(!b.equals("BYE"))

                   {

                     out.println("请输入您要发送的信息:"+b);//如果输入的不是“BYE”,就向对方输出

                     System.in.read(a);

                     b=new String(a,0);

                     b=b.trim();

                   }

                    out.println(b); 

                }

                 catch(Exception e)//捕获程序异常

                 {

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

                  }

                 finally

                 {

                     is.close();//关闭输入流

                       os.close();//关闭输出流

                       socket.close();//关闭socket

                 }

}

}

四、程序运行过程

1.运行客户端程序,当客户端程序运行后,服务器端立即显示连接成功并等待客户端发送信息,结果如下图.

                       

                   服务器程序的运行结果

                     客户端程序运行后的结果

2.客户端向服务器端发送信息,如客户端发送信息“123456789”,服务器端显示客户端发来的信息,运行结果如下图。

3.当客户端向服务器端发送信息“BYE”时,即关闭连接,如下图所示。

五、实验心得

首先我把类aa申明成为public类型,运行出现以下问题:类bb是公共的,应在名为bb.java的文件中申明。经过java书籍知:没有包的类不能被申明为public。

服务器端的端口号必须与客户端的端口号一致。若不一致,会提示“java.net.ConnectException: Connection refused: connect”;但是服务器端获取的不一定就是客户端的端口号,服务器端会在任意一个空闲的端口创建socket对象,与客户端连接;而客户端获取的端口号即为服务器提供的端口号.

端口号的选择一定要在1024以上,我先试图在100端口建立连接,运行程序时抛出BindException异常,即端口已被绑定。选择1024以上就是怕出现BindException异常,当并不是10245以下所有端口号都被绑定了。

在实验过程中,我巩固了以前基础的java知识。初步熟悉并掌握了try-catch-finally的结构,学习了解异常处理的作用。了解Socket类与ServerSocket类的作用与用法,会用一些Socket类与ServerSocket类的重要方法。并且初步了解java中用来实现客户端TCP操作Socket类,这个类本身使用直接代码通过主机操作系统的本地TCP栈进行通信。

 

第二篇:Socket通信实验

计算机网络实验报告

实验三 Socket通信实验

姓 名:

班 级:计科1101班 学 号:0909110122 实验时间:11月27日

目录

一、实验目的与要求------------------------------------------------------3

二、编程语言和环境------------------------------------------------------3

三、问题分析---------------------------------------------------------------4

四、具体实现及源代码---------------------------------------------------5

五、调试与运行结果------------------------------------------------------8

六、实验心得--------------------------------------------------------------9

2

一、 实验目的与要求

网络编程是通过使用套接字来达到进程间通信目的的编程,Socket编程是网络编程的主流工具,Socket API是实现进程间通信的一种编程设施,也是一种为进程间提供底层抽象的机制,提供了访问下层通信协议的大量系统调用和相应的数据结构。本实验利用Socket API编写网络通信程序,具体实验要求及内容如下:

1. 掌握VB、VC++、VS或JAVA等集成开发环境编写网络程序的方法;

2.

3.

4.

5. 掌握客户/服务器(C/S)应用的工作方式; 学习网络中进程之间通信的原理和实现方法; 理解单播、组播和广播的原理并比较其不同之处; 要求本机既是客户端又是服务器端;

所编写的程序应具有如下功能:

1. 具有点对点通信功能,任意客户端之间能够发送消息;

2. 具有群组通信功能,客户端能够向组内成员同时发送消息,其

他组成员不能收到;

3. 具有广播功能,客户端能够向所有其他成员广播消息;

3

二、 编译语言与环境

1. 编程语言C/C++/C#/Java等均可;本次实验采用C语言版本

2. 编程环境Windows(MS Visual系列,VC/VB/VS.Net;)和Linux

(编辑器vi+编译器GCC)均可;在Windows下可使用。

三、 问题分析

1、建立连接

1)服务程序调用socket创建一个新的套接字,并在传输层实体中分配表空间,返回一个文件描述符用于以后调用中使用该套接字;调用bind将一个地址赋予该套接字,使得远程客户程序能访问该服务程序;调用listen分配数据空间,以便存储多个用户的连接建立请求;调用accept将服务程序阻塞起来,等待接收客户程序发来的连接请求。当传输层实体接收到建立连接的TPDU时,新创建一个和原来的套接字相同属性的套接字并返回其文件描述符。服务程序创建一个子进程处理此次连接,然后继续等待发往原来套接字的连接请求。

2)客户程序调用socket创建一个新的套接字,并在传输层实体中分配表空间,返回一个文件描述符用于在以后的调用中使用该套接字;调用connect阻塞客户程序,传输层实体开始建立连接,当连接建立完成时,取消阻塞;

2、数据传输

双方使用send和receive完成数据的全双工发送。

3、释放连接

每一方使用close原语单独释放连接。

4

四、 具体实现及源代码

服务器端

#include <Winsock2.h>

#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

void main()

{

int err; // 错误信息

int len;

char sendBuf[100]; // 发送至客户端的字符串 char recvBuf[100]; // 接受客户端返回的字符串

SOCKET sockServer; // 服务端 Socket

SOCKADDR_IN addrServer;// 服务端地址

SOCKET sockClient; // 客户端 Scoket

SOCKADDR_IN addrClient;// 客户端地址

WSADATA wsaData; // winsock 结构体

WORD wVersionRequested;// winsock 的版本

// 配置 Windows Socket版本

wVersionRequested = MAKEWORD( 2, 2 );

// 初始化 Windows Socket

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 )

{

// 启动错误,程序结束

return;

}

/*

* 确认WinSock DLL支持2.2

* 请注意如果DLL支持的版本大于2.2至2.2

* 它仍然会返回wVersion2.2的版本

*/

5

if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )

{

// 启动错误,程序结束

WSACleanup(); // 终止Winsock 2 DLL (Ws2_32.dll) 的使用 return;

}

// 定义服务器端socket

sockServer = socket(AF_INET, SOCK_STREAM, 0);

// 设置服务端 socket

addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 本机IP addrServer.sin_family = AF_INET; // 协议类型是INET

addrServer.sin_port = htons(6000); // 绑定端口6000

// 将服务器端socket绑定在本地端口

bind(sockServer, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));

// Listen 监听端口

listen(sockServer, 5); // 5 为等待连接数目

printf("服务器已启动:\n监听中...\n");

len = sizeof(SOCKADDR);

while (1)

{

// accept 会阻塞进程,直到有客户端连接上来为止

sockClient = accept(sockServer, (SOCKADDR *)&addrClient, &len); // 当客户端连接上来时, 拼接如下字符串

sprintf(sendBuf, "欢迎 ip: %s 的用户连接, 这里是 Lellansin 的服务器\n", inet_ntoa(addrClient.sin_addr));

// 向客户端发送字符串

send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);

// 获取客户端返回的数据

recv(sockClient, recvBuf, 100, 0);

// 打印客户端返回的数据

printf("%s\n", recvBuf);

// 关闭socket

closesocket(sockClient);

}

6

}

客户端

#include <Winsock2.h>

#include <stdio.h>

#pragma comment(lib, "ws2_32.lib")

void main()

{

int err;

char *message;

char recvBuf[100];

SOCKET sockClient; // 客户端 Scoket

SOCKADDR_IN addrServer; // 服务端地址

WSADATA wsaData;

WORD wVersionRequested;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 )

{

return;

}

if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )

{

// 启动错误,程序结束

WSACleanup( );

return;

}

// 新建客户端 scoket

sockClient = socket(AF_INET, SOCK_STREAM, 0);

// 定义要连接的服务端地址

addrServer.sin_addr.S_un.S_addr = inet_addr("175.0.170.28"); // 目标IP (175.0.170.28是本机地址)

addrServer.sin_family = AF_INET; // 协议类型是INET

7

addrServer.sin_port = htons(6000); // 连接端口1234

// 让 sockClient 连接到 服务端

connect(sockClient, (SOCKADDR *)&addrServer, sizeof(SOCKADDR));

// 从服务端获取数据

recv(sockClient, recvBuf, 100, 0);

// 打印数据

printf("%s\n", recvBuf);

message = "服务端你好~";

// 发送数据到服务端

send(sockClient, message, strlen(message) + 1, 0);

// 关闭socket

closesocket(sockClient);

WSACleanup();

getchar(); // 暂停

}

五、 运行结果

Socket通信实验

Socket通信实验

六、 实验心得

通过本次实验能够感受到网络在实际当中的运用,使我对网络编 8

程有了更深的概念。同时让我发现自己知识结构的欠缺。虽然基本功能已经实现,但还是存在很多不稳定的问题尚待解决。

此次实验是对Socket的一个应用,让我更深的了解了Socket

函数的作用及使用方法。实验过程中遇到了很多的问题,例如:程序只能通信一次。刚开始我以为建立的socket套接口只要建立一次并更新连接地址就可以多次使用。当初不知道问题存在的在于这,在程序加入很多错误报告代码,发现再客户端再次connect的时候返回负值。在网上查看很多相关代码之后,发现问题所在,把建立socket的代码写进客户端的循环体中,每次通信都重新建立socket套接口就可以了。

9

相关推荐