网络编程之TCP/UDP及其流程比较

TCP与UDP的区别

  1. 基于连接与无连接
  2. 对系统资源的要求(TCP较多,UDP少)
  3. UDP程序结构较简单
  4. 流模式与数据报模式
    TCP保证数据正确性,UDP可能丢包
    TCP保证数据顺序,UDP不保证

具体编程时的区别

  1. socket()的参数不同
  2. UDP Server不需要调用listen和accept
  3. UDP收发数据用sendto/recvfrom函数
  4. TCP:地址信息在connect/accept时确定
    UDP:在sendto/recvfrom函数中每次均 需指定地址信息
  5. UDP:shutdown函数无效

部分满足以下几点要求时,应该采用UDP 面向数据报方式

  1. 网络数据大多为短消息
  2. 拥有大量Client
  3. 对数据安全性无特殊要求
  4. 网络负担非常重,但对响应速度要求高

例子:ICQ、ping

 

image

服务器程序流程(多进程):

  1. 程序初始化
  2. 填写本机地址信息
  3. 绑定并监听一个固定的端口
  4. 收到Client的连接后建立一个socket连接
  5. 产生一个新的进程与Client进行通信和信息处理
  6. 子通信结束后中断与Client的连接

客户端程序流程:

  1. 程序初始化
  2. 填写服务器地址信息
  3. 连接服务器
  4. 与服务器通信和信息处理
  5. 通信结束后断开连接

 

服务器代码

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <sys/wait.h> 
#define MYPORT 3490                 /* 监听的端口 */ 
#define BACKLOG 10                 /* listen的请求接收队列长度 */ 
void main() { 
int sockfd, new_fd;             /* 监听端口,数据端口 */ 
struct sockaddr_in sa;         /* 自身的地址信息 */ 
struct sockaddr_in their_addr; /* 连接对方的地址信息 */ 
int sin_size; 
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
perror("socket"); 
exit(1);
} 
sa.sin_family = AF_INET; 
sa.sin_port = htons(MYPORT);         /* 网络字节顺序 */ 
sa.sin_addr.s_addr = INADDR_ANY;     /* 自动填本机IP */ 
bzero(&(sa.sin_zero), 8);             /* 其余部分置0 */ 
if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { 
perror("bind"); 
exit(1);
} 
if (listen(sockfd, BACKLOG) == -1) { 
perror("listen"); 
exit(1);
} 
/* 主循环 */ 
while(1) { 
sin_size = sizeof(struct sockaddr_in); 
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) 
if (new_fd == -1) { 
perror("accept"); 
continue;
} 
printf(”Got connection from %s\n", inet_ntoa(their_addr.sin_addr)); 
if (fork() == 0) { 
/* 子进程 */ 
if (send(new_fd, "Hello, world!\ n", 14, 0) == -1) 
perror("send");
close(new_fd); 
exit(0);
} 
close(new_fd); 
/*清除所有子进程 */ 
while(waitpid(-1,NULL,WNOHANG) > 0);
}
} 

 

客户端代码

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#define PORT 3490 /* Server的端口 */ 
#define MAXDATASIZE 100 /*一次可以读的最大字节数 */ 
int main(int argc, char *argv[]) 
{ 
int sockfd, numbytes; 
char buf[MAXDATASIZE]; 
struct hostent *he; /* 主机信息 */ 
struct sockaddr_in their_addr; /* 对方地址信息 */ 
if (argc != 2) { 
fprintf(stderr,"usage: client hostname\n"); 
exit(1);
} 
/* get the host info */ 
if ((he=gethostbyname(argv[1])) == NULL) { 
/* 注意:获取DNS信息时,显示出错需要用herror而不是perror */ 
herror("gethostbyname"); 
exit(1);
} 
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { 
perror("socket"); 
exit(1);
} 
their_addr.sin_family = AF_INET; 
their_addr.sin_port = htons(PORT); /* short, NBO */ 
their_addr.sin_addr = *((struct in_addr *)he->h_addr); 
bzero(&(their_addr.sin_zero), 8); /* 其余部分设成0 */ 
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { 
perror("connect"); 
exit(1);
} 
if ((numbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1) { 
perror("recv"); 
exit(1);
} 
buf[numbytes] = '\0'; 
printf("Received: %s",buf); 
close(sockfd); 
return 0;
} 

 

image

服务器程序流程(单进程):

  1. 程序初始化
  2. 填写本机地址信息
  3. 绑定一个固定的端口
  4. 收到Client的数据报后进行处理与通信
  5. 通信结束后断开连接

客户端程序流程:

  1. 程序初始化
  2. 填写服务器地址信息
  3. 连接服务器
  4. 与服务器通信和信息处理
  5. 通信结束后断开连接

UDP方式下服务器与客户端程序差别不大,仅第三步不同。

 

服务器

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <sys/wait.h> 
#define MYPORT 3490 /* 监听端口 */ 
void main() 
{ 
int sockfd; /* 数据端口 */ 
struct sockaddr_in my_addr; /* 自身的地址信息 */ 
struct sockaddr_in their_addr; /* 连接对方的地址信息 */ 
int sin_size, retval; 
char buf[128]; 
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 
perror("socket"); 
exit(1);
} 
my_addr.sin_family = AF_INET; 
my_addr.sin_port = htons(MYPORT); /* 网络字节顺序 */ 
my_addr.sin_addr.s_addr = INADDR_ANY; /* 自动填本机IP */ 
bzero(&(my_addr.sin_zero), 8); /* 其余部分置0 */ 
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) { 
perror("bind"); 
exit(1);
} 
/* 主循环 */ 
while(1) {  
retval = recvfrom(sockfd, buf, 128, 0, (struct sockaddr *)&their_addr, &sin_size); 
printf("Received datagram from %s\n",inet_ntoa(their_addr.sin_addr)); 
if (retval == 0) { 
perror (“recvfrom"); 
close(sockfd); 
break;
} 
retval = sendto(sockfd, buf, 128, 0, (struct sockaddr *)&their_addr, sin_size);
}
} 

客户端

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#define PORT 3490 /* Server的端口 */ 
#define MAXDATASIZE 100 /*一次可以读的最大字节数 */ 
int main(int argc, char *argv[]) 
{ 
int sockfd, numbytes, sin_size; 
char buf[MAXDATASIZE] = “Hello, world!”; 
struct hostent *he; /* 主机信息 */ 
struct sockaddr_in their_addr; /* 对方地址信息 */ 
if (argc != 2) { 
fprintf(stderr,"usage: client hostname\n"); 
exit(1);
} 
/* get the host info */ 
if ((he=gethostbyname(argv[1])) == NULL) { 
herror("gethostbyname"); 
exit(1);
} 
if ((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1) { 
perror("socket"); 
exit(1);
} 
their_addr.sin_family = AF_INET; 
their_addr.sin_port = htons(PORT); /* short, NBO */ 
their_addr.sin_addr = *((struct in_addr *)he->h_addr); 
bzero(&(their_addr.sin_zero), 8); /* 其余部分设成0 */ 
numbytes = sendto(sockfd, buf, MAXDATASIZE, 0, (struct sockaddr *)&their_addr,sizeof(their_addr)); 
if (numbytes == -1) { 
perror(“sendto"); 
exit(1);
} 
printf(“Send: %s",buf); 
numbytes = recvfrom(sockfd, buf, MAXDATASIZE, 0, (struct sockaddr *)&their_addr, &sin_size); 
if (numbytes == -1) { 
perror("recvfrom"); 
exit(1);
} 
buf[numbytes] = '\0'; 
printf("Received: %s",buf); 
close(sockfd); 
return 0;
} 

https://www.cnblogs.com/chenxizhang/archive/2009/04/14/1435777.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值