实验名称:利用Socket进行网络编程
班级:软件
实验目的 学号:0 姓名:
熟悉和掌握socket编程的基本理论和方法。掌握基于TCP和UDP的工作原理以及Socket编程的一般方法,能够编写简单的网络应用程序。
实验要求
掌握一些windows XP下的网络命令,记录实验的过程、结果以及遇到的问题及解决方法,并撰写实验总结。
实验过程
1. 了解Socket编程的工作过程
2. 实用UDP进行编程,实现简单的聊天程序
3. 下图为我自己编写的实验代码,该聊天程序,实现了客户端和服务器之间的聊天功能,使用UDP和线程相关知识编写而成。
当客户端输入聊天内容后,服务器收到聊天内容,然后,服务器可以回复客户端,如下图为服务器端的实验结果。
4.具体代码见附录
调试过程
实验过程总体比较顺利,但是在客户端,开始只声明了一个DatagramPacket对象,即我在客户端发送数据,和接受数据时,都只用这一个packet,开始认为,接收到的新的packet会覆盖掉原来的那个,但是事实上是,收到的packet确实被收到的数据更新了,但是由于这个对象在内存中的对象还是和发送是声明的那个一样,所以,如果客户端发送三个字,而服务器恢复客户端5个字,结果客户端只能收到三个字,因为,客户端的packet在发送数据时就已经确定了它发送和接受数据的长度,即三个字,所以导致,在客户端发送内容少于服务器回复的内容时,客户端只能接收到服务器发来的部分内容。后来,在客户端又声明了一个新的接受数据的DatagramPacket,问题得以解决。
总结
经过这次试验,我进一步理解和复习了UDP的socket编程的工作过程和原理,对比TCP,UDP更加简单,快速,因为它本身就是面向无连接的,所以在编程的时候,服务器和客户端其实分得 不是很清楚,许多代码都可以共用,通信的双方处于基本对等的地位, 并且在这次试验中,在修改客户端的DatagramPacket 时,得到的经验很宝贵,让我进一步理解了对象在内存中的实际模型,所以,在实际编程中,一定要实时的在自己的脑海中树立内存模型的概念
附录
/*客户端代码*/
package threadUDPChat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client implements Runnable{
DatagramSocket sktClient ; DatagramPacket paktRecv; DatagramPacket paktSend; InetAddress address; String content; int length; int port; byte [] bufSend; byte [] bufRecv; public Client() { try { sktClient = new DatagramSocket(); this.address = InetAddress.getByName("127.0.0.1"); this.port = 9999; // TODO Auto-generated constructor stub
} } catch (Exception e) { } } @Override public void run() { } public static void main(String[] args) { } Client c = new Client(); Thread t = new Thread(c); t.start(); // TODO Auto-generated method stub while(true){ } try { } BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); content = br.readLine(); //content = "hello , server ..."; bufSend = content.getBytes(); this.paktSend = new DatagramPacket(bufSend, bufSend.length, address, port); this.sktClient.send(paktSend); //System.out.println("已发送信息"); //this.sktClient.close(); //接收 this.bufRecv = new byte[100]; this.paktRecv = new DatagramPacket(bufRecv, bufRecv.length); this.sktClient.receive(paktRecv); this.content = new String(this.paktRecv.getData(),0,this.paktRecv.getLength()); System.out.println(this.paktRecv.getAddress().getHostName()+":"+content); //System.out.println("收到服务器信息"); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) {
/*服务器端*/
package threadUDPChat;
import java.io.BufferedReader; import java.io.InputStreamReader;
import java.net.DatagramPacket; import java.net.DatagramSocket;
public class Server implements Runnable{
DatagramSocket sktServer ; DatagramPacket paktRecv; DatagramPacket paktSend; String content; int length; int port; byte [] bufSend; byte [] bufRecv; public Server() { } @Override public void run() { // TODO Auto-generated method stub while(true){ try { this.bufRecv = new byte[100]; this.paktRecv = new DatagramPacket(bufRecv, bufRecv.length); this.sktServer.receive(paktRecv); this.content = new String(this.paktRecv.getData(),0,this.paktRecv.getLength()); System.out.println(this.paktRecv.getAddress().getHostName()+":"+content); //System.out.println("收到客户信息"); //发送 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); content = br.readLine(); //content = "hello , client ..."; bufSend = content.getBytes(); this.paktSend = new DatagramPacket(bufSend, bufSend.length, this.paktRecv.getAddress(), this.sktServer.send(paktSend); //System.out.println("已发送信息"); //this.sktServer.close(); } catch (Exception e) { // TODO Auto-generated catch block // TODO Auto-generated constructor stub try { } this.sktServer=new DatagramSocket(9999); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); this.paktRecv.getPort());
} } } } e.printStackTrace(); public static void main(String[] args) { } Server s = new Server(); Thread t = new Thread(s); t.start();
计算机网络实验报告
班级:
姓名:
学号:
实验一
一. 实验目的及要求
编写程序,模拟距离矢量路由算法的路由表交换过程,演示交换后的路由表的变化。
二. 实验原理
距离矢量路由算法是这样工作的:每个路由器维护一张路由表(即一个矢量),它以网络中的每个路由器为索引,表中列出了当前已知的路由器到每个目标路由器的最佳距离,以及所使用的线路。通过在邻居之间相互交换信息,路由器不断地更新他们的内部路由表。
举例来说,假定使用延迟作为“距离”的度量标准,并且该路由器发送一个列表,其中包含了他到每一个目标路由器的延时估计值;同时,他也从每个邻居路由器接收到一个类似的列表。假设一个路由器接收到来自邻居x的一个列表,其中x(i)表示x估计的到达路由器i所需要的时间。如果该路由器知道他到x的延时为m毫秒,那么他也知道在x(i)+m毫秒之间内经过x可以到达路由器i。一个路由器针对每个邻居都执行这样的计算,就可以发现最佳的估计值,然后在新的路由器表中使用这个最佳的估计值以及对应的输出路线。
三.源程序:
#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
#include "graphics.h"
#include "dos.h"
#define VERNUM 7
typedef struct
{
int dis;
int flag;
int flag2;
}RoutNode;
char tmp[10];
RoutNode data[VERNUM][VERNUM]; void welcome();
void InitRoutData(FILE* pfile);
void PrintRoutData();
void SendInf(int recv, int send);
void Exchange();
int main()
{
int start, end, i, j, m, n;
FILE *pfile;
welcome();
pfile = fopen("1.txt", "r");
if (pfile == NULL)
{
printf("the file wrong,press any key to come back.\n"); getch();
return;
}
else
InitRoutData(pfile);
fclose(pfile);
printf("\nthe original route table:\n");
for (i = 0; i<VERNUM; i++)
{
printf("%c||", i + 65);
for (j = 0; j < VERNUM; j++)
if (data[i][j].dis > 0)
printf("<%c %d> ", j + 65, data[i][j].dis); printf("\n");
}
PrintRoutData();
getch();
for (i = 0; i < VERNUM; i++)
{
for (m = 0; m < VERNUM; m++)
for (n = 0; n < VERNUM; n++)
data[m][n].flag = 0;
Exchange();
PrintRoutData();
getch();
}
printf("\nexchange the route table:\n");
return 0;
}
void welcome()
{
int gdriver=DETECT,gmode;
registerbgidriver(EGAVGA_driver);
initgraph( &gdriver, &gmode,"C:\Win-TC"); cleardevice();
setbkcolor(CYAN);
setviewport(0,0,639,479,1);
clearviewport();
setbkcolor(BLUE);
setcolor(14);
rectangle(200,200,440,280);
setfillstyle(1,5);
floodfill(300,240,14);
settextstyle(0,0,2);
outtextxy(50,30,"Distance Vector Routing Algorithm"); setcolor(15);
settextstyle(1,0,4);
outtextxy(260,214,"Welcome to use!"); line(0,80,640,80);
getch();
delay(300);
cleardevice();
}
void InitRoutData(FILE* pfile)
{
char num[10];
int i = 0;
char c;
int m, n;
fseek(pfile, 0, 0);
for (m = 0; !feof(pfile) && m < 7; m++)
{
for (n = 0; !feof(pfile) && n < 7; n++)
{
while (!feof(pfile))
{
c = fgetc(pfile);
if (c == ',')
{
num[i] = '\0';
data[m][n].dis = atoi(num); data[m][n].flag = 0;
data[m][n].flag = 0;
i = 0;
break;
} /*end of if*/
else if ((c >= '0' && c <= '9') || c == '-') {
num[i++] = c;
} /*end of else if*/
} /*end of while*/
} /*end of for (n = 0*/
} /*end of for (m = 0*/
}
void PrintRoutData()
{
int i, j;
for (i = 0; i < VERNUM; i++)
{
settextstyle(1,0,3);
sprintf(tmp," %c",i + 65);
outtextxy(i*80+50,130,tmp);
outtextxy(10,160+i*40,tmp);
}
for (j = 0; j< VERNUM; j++)
{
for (i = 0; i < VERNUM; i++)
{
if (data[i][j].dis <= 0&&i!=j)
{
if(data[i][j].flag2 ==1)
{
setfillstyle(SOLID_FILL,5);
bar(80*i+50,40*j+155,80*i+120,40*j+185); delay(50000);
data[i][j].flag2 =0;
}
setfillstyle(SOLID_FILL,3);
bar(80*i+50,40*j+155,80*i+120,40*j+185); settextstyle(1,0,2);
sprintf(tmp,"-");
outtextxy(80*i+65,40*j+165,tmp); }
else
if(data[i][j].dis >=0)
{
if(data[i][j].flag2 ==1)
{
setfillstyle(SOLID_FILL,5);
bar(80*i+50,40*j+155,80*i+120,40*j+185);
delay(50000);
data[i][j].flag2 =0;
}
setfillstyle(SOLID_FILL,3);
bar(80*i+50,40*j+155,80*i+120,40*j+185);
settextstyle(1,0,2);
sprintf(tmp,"%d",data[i][j].dis);
outtextxy(80*i+65,40*j+165,tmp);
}
} /*end of for (j = 0*/
} /*end of for (i = 0*/
}
void SendInf(int recv, int send)
{
int i;
for (i = 0; i < VERNUM; i++)
{
if (data[send][i].dis > 0&& data[send][i].flag!=1) { if (data[recv][i].dis <= 0&&recv!=i) {
data[recv][i].dis = data[send][i].dis + data[recv][send].dis; data[recv][i].flag =1;
data[recv][i].flag2 =1;
}
else if (data[recv][i].dis > data[send][i].dis + data[recv][send].dis)
{
data[recv][i].dis = data[send][i].dis + data[recv][send].dis; data[recv][i].flag =1;
data[recv][i].flag2 =1;
}
} /*end of if*/
} /*end of for*/
}
void Exchange()
{
int i, j;
for (i = 0; i < VERNUM; i++)
{
for (j = 0; j < VERNUM; j++)
{
if (data[i][j].dis > 0&& data[i][j].flag!=1)
{
SendInf(i, j);
} /*end of if*/
} /*end of for (j = 0*/
} /*end of for (i = 0*/
}
四、 实验心得体会
通过本次实验训练,我了解了距离矢量路由算法的基本原理,复习了C语言编程的内容,通过对路由算法的实现,加深了对路由表交换的理解。
实验二
一、 实验目的及要求
编写程序,联系Socket编程和TCP/IP协议的应用,要求实现Server端和Client端的信息通信。
二、实验原理
在TCP/IP编程中,为客户端和服务器端提供相同的端口号和IP地址号,实现Server端和Client端互联,运用Java文件流的知识,实现两端的信息传递。
三、源程序
/********************ChatClient*********************/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.io.IOException;
import java.net.*;
public class ChatClient extends Frame{
Socket s = null;
DataOutputStream dos = null;
TextField tf = new TextField();
TextArea ta = new TextArea();
public static void main(String[] args) { new ChatClient().launchFrame(); } public void launchFrame() { setLocation(400,300); this.setSize(300,300); add(tf,BorderLayout.SOUTH); add(ta,BorderLayout.NORTH); pack(); tf.addActionListener(new tfListener()); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { disconn(); System.exit(0); } }); setVisible(true); conn(); } public void conn () { try { s = new Socket("127.0.0.1",5555); dos = new DataOutputStream(s.getOutputStream()); System.out.println("客户端连接成功!"); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void disconn() { try { dos.close(); s.close(); } catch (IOException e) { e.printStackTrace(); }
}
private class tfListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tf.getText().trim();
ta.setText(str);
tf.setText("");
try {
dos.writeUTF(str);
dos.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
/********************ChatServer******************/
import java.io.IOException;
import java.net.*;
import java.io.*;
public class ChatServer {
public static void main(String[] args) {
boolean started = false;
try {
ServerSocket ss = new ServerSocket(5555);
started = true;
while(started) {
boolean bConn = false;
Socket s = ss.accept();
bConn = true;
System.out.println("一个客户端已连接");
DataInputStream dis = new DataInputStream(s.getInputStream()); while(bConn){
String str = dis.readUTF();
System.out.println(str);
}
} } dis.close(); } } catch (IOException e) { e.printStackTrace(); }
四、实验心得体会
通过本次实验的练习,熟悉了TCP/IP协议,对套接字等概念有了深入的了解,对用Java语言实现Socket编程并实现客户端和服务器端的信息交互有了一定的了解。
实验名称利用Socket进行网络编程班级软件实验目的学号0姓名熟悉和掌握socket编程的基本理论和方法掌握基于TCP和UDP的工…
实验报告实验一Socket编程一实验目的通过socket程序的编写调试掌握socket编程的基本方法了解客户端与服务器端的特点掌握…
姓名学院实验时间计算机网络实验题目Socket编程实验1基于UDP的Socket编程实验2基于TCP的Socket编程学号年级目录…
数学与计算机学院计算机网络实验报告年级学号姓名成绩专业网络工程实验地点指导教师实验项目socket点对点聊天工具实验日期20xx5…
实验二基于TCPUDP的Socket编程实验目的熟悉和掌握socket编程的基本理论和方法掌握基于TCP和UDP的工作原理以及So…
问题一:写C++Socket有关的程序遇到,以下错误错误2errorLNK20xx:无法解析的外部符号__imp__WSAClea…
大连民族学院计算机科学与工程学院实验报告实验题目socket编程综合实验课程名称网络编程技术实验类型演示性验证性操作性设计性综合性…
实验报告实验一Socket编程一实验目的通过socket程序的编写调试掌握socket编程的基本方法了解客户端与服务器端的特点掌握…
姓名学院实验时间计算机网络实验题目Socket编程实验1基于UDP的Socket编程实验2基于TCP的Socket编程学号年级目录…