3socket编程:UDP编程



1 C/S模型—UDP

UDP处理模型

说明:

由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实现。

编译运行server,在两个终端里各开一个client与server交互,看看server是否具有并

发服务的能力。用Ctrl+C关闭server,然后再运行server,看此时client还能否和server联

系上。和前面TCP程序的运行结果相比较,体会无连接的含义。

2
案例说明:

Server.c


#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<ctype.h>

#include"wrap.h"

#define MAXLINE 80

#define SERV_PORT 8000

int main(void)

{

struct sockaddr_in servaddr,cliaddr;

socklen_t cliaddr_len;

int sockfd;

char buf[MAXLINE];

char str[INET_ADDRSTRLEN];

int i,n;

sockfd = Socket(AF_INET,SOCK_DGRAM,0);

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(SERV_PORT);

Bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

printf("Accepting connections...\n");

while(1) {

cliaddr_len = sizeof(cliaddr);

n = recvfrom(sockfd,buf,MAXLINE,0,

(struct sockaddr *)&cliaddr,&cliaddr_len);

if(n == -1)

perr_exit("recvfrom error");

printf("received from %s at PORT %d\n",

inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),

ntohs(cliaddr.sin_port));

for(i = 0;i<n;i++){

buf[i] = toupper(buf[i]);

}

n = sendto(sockfd,buf,n,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));

if(n== -1)

perr_exit("sendto error");

}

}

Client.c


#include<stdio.h>

#include<string.h>

#include<unistd.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include"wrap.h"

#define MAXLINE 80

#define SERV_PORT 8000

int main(int argc,char *argv[])

{

struct sockaddr_in servaddr;

int sockfd,n;

char buf[MAXLINE];

char str[INET_ADDRSTRLEN];

socklen_t servaddr_len;

sockfd = Socket(AF_INET,SOCK_DGRAM,0);

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family = AF_INET;

inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);

servaddr.sin_port = htons(SERV_PORT);

while(fgets(buf,MAXLINE,stdin) != NULL) {

n = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&servaddr,

sizeof(servaddr));

if(n == -1)

perr_exit("sendto error");

n = recvfrom(sockfd,buf,MAXLINE,0,NULL,0);

if(n == -1)

perr_exit("recvfrom error");

Write(STDOUT_FILENO,buf,n);

}

Close(sockfd);

return 0;

}

Wrap.h


#ifndef __WRAP_H_

#define __WRAP_H_

void perr_exit(const char *s);

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);

void Bind(int fd, const struct sockaddr *sa, socklen_t salen);

void Connect(int fd, const struct sockaddr *sa, socklen_t salen);

void Listen(int fd, int backlog);

int Socket(int family, int type, int protocol);

ssize_t Read(int fd, void *ptr, size_t nbytes);

ssize_t Write(int fd, const void *ptr, size_t nbytes);

void Close(int fd);

ssize_t Readn(int fd, void *vptr, size_t n);

ssize_t Writen(int fd, const void *vptr, size_t n);

static ssize_t my_read(int fd, char *ptr);

ssize_t Readline(int fd, void *vptr, size_t maxlen);

#endif

Wrap.c


#include <stdlib.h>

#include <errno.h>

#include <sys/socket.h>

void perr_exit(const char *s)

{

perror(s);

exit(1);

}

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)

{

int n;

again:

if ( (n = accept(fd, sa, salenptr)) < 0) {

if ((errno == ECONNABORTED) || (errno == EINTR))

goto again;

else

perr_exit("accept error");

}

return n;

}

void Bind(int fd, const struct sockaddr *sa, socklen_t salen)

{

if (bind(fd, sa, salen) < 0)

perr_exit("bind error");

}

void Connect(int fd, const struct sockaddr *sa, socklen_t salen)

{

if (connect(fd, sa, salen) < 0)

perr_exit("connect error");

}

void Listen(int fd, int backlog)

{

if (listen(fd, backlog) < 0)

perr_exit("listen error");

}

int Socket(int family, int type, int protocol)

{

int n;

if ( (n = socket(family, type, protocol)) < 0)

perr_exit("socket error");

return n;

}

ssize_t Read(int fd, void *ptr, size_t nbytes)

{

ssize_t n;

again:

if ( (n = read(fd, ptr, nbytes)) == -1) {

if (errno == EINTR)

goto again;

else

return -1;

}

return n;

}

ssize_t Write(int fd, const void *ptr, size_t nbytes)

{

ssize_t n;

again:

if ( (n = write(fd, ptr, nbytes)) == -1) {

if (errno == EINTR)

goto again;

else

return -1;

}

return n;

}

void Close(int fd)

{

if (close(fd) == -1)

perr_exit("close error");

}

ssize_t Readn(int fd, void *vptr, size_t n)

{

size_t  nleft;

ssize_t nread;

char   *ptr;

ptr = vptr;

nleft = n;

while (nleft > 0) {

if ( (nread = read(fd, ptr, nleft)) < 0) {

if (errno == EINTR)

nread = 0;

else

return -1;

} else if (nread == 0)

break;

nleft -= nread;

ptr += nread;

}

return n - nleft;

}

ssize_t Writen(int fd, const void *vptr, size_t n)

{

size_t nleft;

ssize_t nwritten;

const char *ptr;

ptr = vptr;

nleft = n;

while (nleft > 0) {

if ( (nwritten = write(fd, ptr, nleft)) <= 0) {

if (nwritten < 0 && errno == EINTR)

nwritten = 0;

else

return -1;

}

nleft -= nwritten;

ptr += nwritten;

}

return n;

}

static ssize_t my_read(int fd, char *ptr)

{

static int read_cnt;

static char *read_ptr;

static char read_buf[100];

if (read_cnt <= 0) {

again:

if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {

if (errno == EINTR)

goto again;

return -1;

} else if (read_cnt == 0)

return 0;

read_ptr = read_buf;

}

read_cnt--;

*ptr = *read_ptr++;

return 1;

}

ssize_t Readline(int fd, void *vptr, size_t maxlen)

{

ssize_t n, rc;

char    c, *ptr;

ptr = vptr;

for (n = 1; n < maxlen; n++) {

if ( (rc = my_read(fd, &c)) == 1) {

*ptr++ = c;

if (c  == ‘\n‘)

break;

} else if (rc == 0) {

*ptr = 0;

return n - 1;

} else

return -1;

}

*ptr  = 0;

return n;

}

时间: 2024-10-07 04:12:05

3socket编程:UDP编程的相关文章

Linux 网络编程——UDP编程

概述 UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的运输层协议,在网络中用于处理数据包,是一种无连接的协议.UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地.由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快. UDP 有如下的特点: 1)邮件系统服务模式的抽象(可通过邮件模型来进行对比) 2)每个分组都携带完整的目的

37 - 网络编程-UDP编程

目录 1 UDP协议 2 UDP通信流程 3 UDP编程 3.1 构建服务端 3.3 常用方法 4 聊天室 5 UDP协议应用 1 UDP协议 UDP是面向无连接的协议,使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包.但是,能不能到达就不知道了.虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议. 2 UDP通信流程 我们先来了解一下,python的socket的通讯流程: 服务端: 创建Socket

udp编程的学习

最近在做一个网络应用小程序(虽然很烦应用层编程...),实现视频数据通过网络无限发送,不关有无网络,数据都发出,用于产品的老化测试. 起初代码是用TCP写的,TCP有连接,产品作为server,起一个监控connect线程,有client连接,监控线程告诉主线程,主线程就将数据发出,没有client连接,主线程则将数据抛空. 但是有这样一个需求,用户插入网线后,PC端的client接收数据,然后强制拔掉网线,这时server还要一直在发送数据(数据是发出还是抛空无所谓),这样实现产品的长时间运行

Socket编程实践(12) --UDP编程基础

UDP特点 无连接,面向数据报(基于消息,不会粘包)的数据传输服务; 不可靠(可能会丢包, 乱序, 重复), 但因此一般情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *a

Linux下的socket编程实践(十) 基本UDP编程细节

在我的这两篇博客中,简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节. http://blog.csdn.net/nk_test/article/details/47733307 http://blog.csdn.net/nk_test/article/details/47756381 下图是一个简单的UDP客户/服务器模型: 我在这里也实现了一个简单的UDP回射服务器/客户端: /**实践: 实现一个基

嵌入式 Linux网络编程(三)——UDP编程模型

嵌入式 Linux网络编程(三)--UDP编程模型 UDP编程模型: UDP循环服务器模型为: socket(...); bind(...); while(1) {    recvfrom(...);    process(...);    sendto(...); } server.c代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #inc

java 网络编程 UDP TCP

网络编程 网络编程主要用于解决计算机与计算机(手机.平板..)之间的数据传输问题. 网络编程: 不需要基于html页面就可以达到数据之间的传输. 比如: feiQ , QQ , 微信....网页编程: 就是要基于html页面的基础上进行数据的交互的. 比如: 珍爱网. oa(办公自动化). 高考的报告系统... 计算机网络: 分布在不同地域 的计算机通过外部设备链接起来达到了消息互通.资源共享的效果就称作为一个计算机网络.网络通讯的三要素:    1. IP    2. 端口号.    3. 协

Linux学习四:UDP编程(上)

关于UDP和TCP对比优缺,这里就不说了. 使用UDP代码所掉用的函数和用于TCP的函数非常类似,这主要因为套接口库在底层的TCP和UDP的函数上加了一层抽象,通过这层抽象使得编程更容易,但失去了一些控制. 二者函数调用唯一的实际区别是soceket函数调用的一个参数,TCP的是SOCK_STREAM,UDP的是SOCK_DGRAM,二者都可以使用recvfrom函数,而recv只用于TCP. 当然函数的变化不是这么简单,因为你要从一种有连接的协议转向到无连接的协议上去.这里写个很简单直接的UD

基于Linux下的UDP编程

一. Linux下UDP编程框架 使用UDP进行程序设计可以分为客户端和服务器端两部分. 1.服务器端程序包括: Ø  建立套接字 Ø  将套接字地址结构进行绑定 Ø  读写数据 Ø  关闭套接字 2.客户端程序包括: Ø  建立套接字 Ø  读写数据 Ø  关闭套接字 3.服务器端和客户端程序之间的差别 服务器端和客户端两个流程之间的主要差别在于对地址的绑定函数(bind()函数),而客户端可以不用进行地址和端口的绑定操作. 二.Linux中UDP套接字函数  从图可知,UDP协议的服务端程序

Node.js开发入门—UDP编程

Node.js也提供了UDP编程的能力,相关类库在"dgram"模块里. 与TCP不同,UDP是无连接的,不保障数据的可靠性,不过它的编程更为简单,有时候我们也需要它.比如做APP的统计或者日志或者流媒体,很多流媒体协议都会用到UDP,网上一搜一大堆. 使用UDP,如果你要发送数据,只需要知道对方的主机名(地址)和端口号,扔一消息过去即可.至于对方收不收得到,听天由命了.这就是数据报服务,类似快递或邮件. 我们这次来介绍一下Node.js里的UDP编程,我会提供一个UDP版本的echo