计算机网络原理实验报告
UDP网络聊天程序设计
班级:计算机1301班
学号:1307010116
姓名:席凤凯
实验五 UDP网络聊天程序设计
一.实验目的:
编程设计基于 UDP 的简单聊天室程序,实现服务器与客户端之间的对话通信功能。
二.实验原理:
网络编程一般都是基于 TCP 或 UDP 的,一般过程如下:
(1)TCP 编程的服务器端与客户端一般步骤:
服务器端:
1、创建一个 socket,用函数 socket();
2、绑定 IP 地址、端口等信息到 socket 上,用函数 bind();
3、开启监听,用函数 listen();
4、接收客户端上来的连接,用函数 accept();
5、收发数据,用函数 send()和 recv(),或者 read()和 write();
6、关闭网络连接;
7、关闭监听;
客户端:
1、创建一个 socket,用函数 socket();
2、设置要连接的对方的 IP 地址和端口等属性;
3、连接服务器,用函数 connect();
4、收发数据,用函数 send()和 recv(),或者 read()和 write();
5、关闭网络连接;
(2) UDP 编程步骤如下:
服务器端:
1、创建一个 socket,用函数 socket();
2、绑定 IP 地址、端口等信息到 socket 上,用函数 bind();
3、循环接收数据,用函数 recvfrom();
4、关闭网络连接;
客户端:
1、创建一个 socket,用函数 socket();
2、设置对方的 IP 地址和端口等属性;
3、发送数据,用函数 sendto();
4、关闭网络连接;
三.实验内容:
编辑代码:
(1)服务器源程序:
#include <stdio.h> 标准输入输出头文件
#include <netinet/in.h> 互联网地址族
#include <arpa/inet.h> LINUX 下 C 语言程序的 INTERNET 定义头文件
#include <unistd.h> 符号常量
#include <fcntl.h> 文件控制
#include <sys/stat.h> 文件状态
#include <sys/types.h> 基本系统数据类型
#include <sys/socket.h> 套接字接口
#define LOCALPORT 4567
//定义本地服务器端口
int main(int argc,char *argv[])
{
int s,len;
struct sockaddr_in addr;
int addr_len;
char msg[256];
int i=0;
/
/ 编写一个函数用来初始化套接字和绑定套接字。
//初始化套接字。 socket 参数第一个是网络套接字族。一般都是 AF_INET。
//第二个参数是套接字类型。 TCP 的是 SOCK_STREAM。
//而 UDP 的是 SOCK_DGRAM 的形式。
//第三个是初始化的协议。一般都是 0。
if (( s= socket(AF_INET, SOCK_DGRAM, 0) )<0)
{
perror("error");
exit(1);
}
else
{
printf("socket created .\n");
printf("socked id: %d \n",s);
printf("remote port: %d \n",LOCALPORT);
/
/创建成功后输出信息。
}
len=sizeof(struct sockaddr_in);
bzero(&addr,sizeof(addr));
addr.sin_family=AF_INET; //地址家族。
addr.sin_port=htons(LOCALPORT); //端口。这个 port 是自己申明的变量,一般自己申明
的端口号要大于 1024。
addr.sin_addr.s_addr=htonl(INADDR_ANY);//地址是一个结构体。用 htonl 把它转化为网
络字节序。
if(bind(s,(struct sockaddr *)&addr,sizeof(addr))<0)
{perror("");
exit(1);
}
else
{printf("bind ok. \n");
printf("local port:%d \n",LOCALPORT);
}//绑定套接字。
while (1)
{
bzero(msg,sizeof(msg));
len =sizeof(struct sockaddr_in);
//因为我们是用 UDP 的方式。所以我们这里用 recvform 来接收数据。若是 TCP 则采用 recv。
//recvform 的参数。第一是套接字,第二个是你要接收的字符缓冲区。
//第三个是缓冲区大小。第四个是标记我们设为 0 就好。
//第五个参数是接收对方地址。第六个是地址长度。
if ((i=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&addr,&len))==-1)
{ printf("error receiving! \n");
exit(1);
}
if(!strcmp("quit\n", msg)) //如果收到“ quit”,表示客户端要结束聊天。
{
sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&addr,len);
printf("Chat end!\n"); //服务器发送“ quit”并结束,输出 Chat end!。
break;
}
printf("The mseeage you recving is:%s \n",msg);
sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&addr,len);
}
}
(2)客户端源代码:
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
socket编程聊天室基本流程#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#define REMOTEPORT 4567 //直接定义连接服务器端口。
#define REMOTEIP "127.0.0.1"
int main(int argc,char *argv[])
{
int s,len;
struct sockaddr_in addr;
int addr_len;
char msg[256];
int i=0;
//定义套接字并初始化,建立成功则输出信息。
if (( s= socket(AF_INET, SOCK_DGRAM, 0) )<0)
{
perror("error");
exit(1);
}
else
{
printf("socket created .\n");
printf("socked id: %d \n",s);
printf("remote ip: %s \n",REMOTEIP);
printf("remote port: %d \n",REMOTEPORT);
}
len=sizeof(struct sockaddr_in);
bzero(&addr,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(REMOTEPORT);
addr.sin_addr.s_addr=inet_addr(REMOTEIP);
while (1)
{
bzero(msg,sizeof(msg));
len = read(STDIN_FILENO,msg,sizeof(msg));
if((sendto(s,msg,sizeof(msg),0,&addr,sizeof(addr)))<0)
{ perror("send message worry!");
exit(1);
}
printf("send message is:%s\n",msg) ;
}
}
四.实验结果截图:
五.修改后的代码
(修改后可以是自己输入端口号和ip号)
客户端代码:
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>    /*包括结构hostent(主机环境),获得主机信息的几个函数*/
int main(int argc,char *argv[])
{
printf("=======================================\n");
printf("=                client                =\n");
printf("=======================================\n");
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct hostent *host;
int nbytes,portnumber;
char buffer[1024];
if (argc!=3){
  fprintf(stderr,"Usage:%s hostname portnumber \a\n",argv[0]);
  exit(1);
}
//获得服务器地址
if ((host=gethostbyname(argv[1]))==NULL){
  fprintf(stderr,"HostName Erro!");
  exit(1);
}
if ((portnumber=atoi(argv[2]))<0){
  fprintf(stderr,"Usage:%s hostname  portnumber \a\n",argv[0]);
  exit(1);
}
//建立客户端Sockfd描述符
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
  fprintf(stderr,"Socket error:%s \a\n",strerror(errno));
  exit(1);
}
//调用函数connect之前,需要指定服务器进程的套接字地址
//填充sockaddr结构
bzero(&server_addr,sizeof (struct sockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
// server_addr.sin_addr= *((struct in_addr *) host->h_addr);
//发起连接请求与远程服务器建立一个连接
if (connect(sockfd,(struct sockaddr *)(&server_addr),sizeof (struct sockaddr))==-1){
  fprintf(stderr,"Bind error:%s \a\n",strerror(errno));
  exit(1);
}
//进行读写数据操作,将数据显示到标准输出上
if ((nbytes=read(sockfd,buffer,1024))==-1){
  fprintf(stderr,"Read error: %s  \n",strerror(errno));
  exit(1);
}
buffer[nbytes]='\\';
  printf("收到: %s \n",buffer);
//结束通信
//关闭连接
close(sockfd);
exit(0);
 
}
服务端代码:
#include <stdio.h>        //标准输入输出头文件

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。