首页 > 编程语言 >TCP、UDP 网络编程

TCP、UDP 网络编程

时间:2022-12-20 17:36:59浏览次数:42  
标签:UDP addr int 编程 TCP fd include buf socket


TCP、UDP 网络编程

实验目的

1.使用 TCP 进行套接字通信
2.使用 UDP 进行套接字通信 实验原理

1.TCP

TCP、UDP 网络编程_socket

2.UDP

TCP、UDP 网络编程_网络通信_02

3.用到的 API

(1)int socket(int domain, int type, int protocol);
根据指定的地址族、数据类型和协议来分配一个 socket 的描述字及其所用的资源。 domain:协议族,常用的有 AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE 其中 AF_INET 代表使用 ipv4 地址
type:socket 类型,常用的 socket 类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、
SOCK_SEQPACKET 等
protocol:协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC 等
(2)int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
把一个地址族中的特定地址赋给 socket
sockfd:socket 描述字,也就是 socket 引用
addr:要绑定给 sockfd 的协地址
addrlen:地址的长度
通常服务器在启动的时候都会绑定一个众所周知的地址(如 ip 地址+端口号),用于提供服务,客 户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的 ip 地 址组合。这就是为什么通常服务器端在 listen 之前会调用 bind(),而客户端就不会调用,而是在 connect()时由系统随机生成一个
(3)int listen(int sockfd, int backlog);
监听 socket
sockfd:要监听的 socket 描述字
backlog:相应 socket 可以排队的最大连接个数
(4)int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
连接某个 socket
sockfd:客户端的 socket 描述字
addr:服务器的 socket 地址
addrlen:socket 地址的长度
(5)int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
TCP 服务器监听到客户端请求之后,调用 accept()函数取接收请求
sockfd:服务器的 socket 描述字
addr:客户端的 socket 地址
addrlen:socket 地址的长度
(6)ssize_t read(int fd, void *buf, size_t count);
读取 socket 内容
fd:socket 描述字
buf:缓冲区
count:缓冲区长度
(7)ssize_t write(int fd, const void *buf, size_t count); 向 socket 写入内容,其实就是发送内容
fd:socket 描述字
buf:缓冲区
count:缓冲区长度
(8)int close(int fd);
socket 标记为以关闭 ,使相应 socket 描述字的引用计数-1,当引用计数为 0 的时候,触发 TCP 客户 端向服务器发送终止连接请求。

实验内容

1.TCP

(1)server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 11111
#define LISTENQ 10 // 可排队的最大连接数
int main() {
//TCP、UDP都只有一种协议满足条件,可以将 protocol 的值设为 0,系统会自动推演出应该使用什么协议
int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//AF_INNT Ipv4地址 创建套接字
struct sockaddr_in addr;
addr.sin_family = AF_INET; //使用IPv4地址
addr.sin_port = htons(PORT); //绑定端口PORT
// serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的IP地址
addr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY 任意地址
//将套接字绑定到 固定IP和固定端口
bind(fd, (struct sockaddr*)&addr, sizeof(addr));//绑定 进行端口和IP地址的绑定
// 将套接字设置为监听模式,等待连接到来
listen(fd, LISTENQ);//监听 //监听队列为LISTENQ

int fd_;
struct sockaddr_in addr_;
int len = sizeof(addr_);
int cnt = 0;
while(1){
printf("等待连接.......\n");
if ((fd_ = accept(fd, (struct sockaddr*)&addr_, &len)) < 0) {//调用 accept 接受请求
printf("error\n");
}
else{
char read_buf[1024] = { 0 };
char *write_buf = "Hello,客户端 client!";
int recvlen = 0;
cnt ++;
printf("success:%d\n", cnt);
// 通过read()、write()接受和发送数据
/*
read(fd_, read_buf,sizeof(read_buf));
printf("%s\n", read_buf);
write(fd_, write_buf,strlen(write_buf));
*/
// 通过recv()、send()接受和发送数据,接收并打印客户端数据

if( ( recvlen = recv(fd_, read_buf, sizeof(read_buf), 0) ) > 0){
printf("%s\n", read_buf);
}
// 发送服务器端数据
send(fd_, write_buf, strlen(write_buf), 0);
}
}


// 关闭连接
close(fd_);
close(fd);
return 0;
}

(2)client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 11111
#define IP "127.0.0.1"

int main() {
int fd = socket(AF_INET, SOCK_STREAM, 0);//创建套接字 流格式套接字(SOCK_STREAM)
// SOCK_STREAM 是一种可靠的、双向的通信数据流,数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送。
//向服务器(特定的IP和端口)发起请求
struct sockaddr_in addr;
addr.sin_family = AF_INET; //使用IPv4地址
addr.sin_port = htons(PORT); //端口
addr.sin_addr.s_addr = inet_addr(IP); //具体的IP地址
//inet_pton(AF_INET, IP, &(addr.sin_addr.s_addr)); //访问的服务器IP 具体的IP地址
// 向服务器发出连接请求
printf("发起连接.......\n");
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {//建立连接
printf("error\n");

}
else {
char read_buf[1024] = { 0 };
char *write_buf = "Hello,服务器 server!";
int recvlen = 0;
printf("success\n");
// 通过write()、read()发送和接受数据

/* write(fd, write_buf, strlen(write_buf));
read(fd, read_buf, sizeof(read_buf) -1 );
printf("%s\n", read_buf);

*/

// 通过recv()、send()发送和接受数据,接收并打印客户端数据
send(fd, write_buf, strlen(write_buf), 0);
// 接收并打印客户端数据
if( ( recvlen = recv(fd, read_buf, sizeof(read_buf), 0) )){
printf("%s\n", read_buf);
}
}

//关闭套接字
close(fd);
return 0;
}

2.UDP

(1)server_.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 11111
#define BUFFSIZE 1024
int main() {
int fd = socket(AF_INET, SOCK_DGRAM, 0);//参数和 tcp 不同
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;
bind(fd, (struct sockaddr*)&addr, sizeof(addr));//无需 listen
char buff[BUFFSIZE];
socklen_t len = sizeof(addr);
int cnt = 0;
//接收数据,把数据原封不动发回给客户
while(1){
int n = recvfrom(fd, buff, BUFFSIZE, 0, (struct sockaddr*)&addr, &len);
if( n == 0 ){
break;
}
cnt ++;
sprintf(buff, "%s:%d", buff, cnt);
sendto(fd, buff, n, 0, (struct sockaddr*)&addr, len);
}

close(fd);

return 0;
}

(2)client_.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 11111
#define BUFFSIZE 1024
int main() {
int fd = socket(AF_INET, SOCK_DGRAM, 0); // 数据报格式套接字(SOCK_DGRAM)
// 数据报套接字是一种不可靠的、不按顺序传递的、以追求速度为目的的套接字
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
char buff[BUFFSIZE] = "服务器被连接的次数:";
struct sockaddr_in addr_;
socklen_t len = sizeof(addr);

//发送数据,打印从服务器发回的数据
sendto(fd, buff, BUFFSIZE, 0, (struct sockaddr*)&addr, len);
recvfrom(fd, buff, BUFFSIZE, 0, (struct sockaddr*)&addr_, &len);

printf("%s\n", buff);
close(fd);

return 0;
}

实验结果

TCP:

TCP、UDP 网络编程_网络通信_03


TCP、UDP 网络编程_套接字_04

UDP:

TCP、UDP 网络编程_服务器_05


TCP、UDP 网络编程_套接字_06


标签:UDP,addr,int,编程,TCP,fd,include,buf,socket
From: https://blog.51cto.com/u_15918664/5956347

相关文章

  • TCP 实现跨平台文件传输
    TCP实现跨平台文件传输实验目的利用TCP完成linux和windows平台的文件传输。实验原理windows与linux上实现tcp文件传输本质上是相同的,只有一些函数调用方式不一......
  • 利用 TCP 完成文件传输的设计
    利用TCP完成文件传输的设计实验目的输入文件路径,利用TCP实现客户文件向服务器的传输,并实现对TCP的基本封装实验原理1.服务器(1)建立socket(2)确定服务器scokaddr_i......
  • 开关量、模拟量、脉冲量分不清楚?PLC最全编程算法详解,看完彻底懂了!
    PLC中无非就是三大量:开关量、模拟量、脉冲量。只在搞清楚三者之间的关系,你就能熟练的掌握PLC了。开关量的计算1、开关量也称逻辑量,指仅有两个取值,0或1、ON或OFF。它是最......
  • 编程常用单词1500个
    很实用的编程英语词库,共收录一千五百余条词汇。第一部分:application应用程式应用、应用程序applicationframework应用程式框架、应用框架应用程序框架architectur......
  • TCP那些你需要掌握的知识
    什么是TCP/IP?TCP/IP协议模型(TransmissionControlProtocol/InternetProtocol),包含了一系列构成互联网基础的网络协议,是Internet的核心协议。并不只有TCP与IP两种协......
  • Angular JS入门 (一)事件监听(二)多控制器思想与模块化编程(三)路由router
    AngularJS入门☀️将流式结构--->模块化一、事件监听1.事件监听前言NG框架中通过对元素标签添加[ng-事件名]指令,来对元素添加事件监听而事件监听的回调函数需要在con......
  • 不要启用 net.ipv4.tcp_tw_recycle
    本文为翻译英文BLOG《​​CopingwiththeTCPTIME-WAITstateonbusyLinuxservers​​》,但并非完整的翻译,译者CFC4N对原文理解后,进行了调整,增加了相关论点论据,跟原文稍......
  • 编程路-基础提升-第七周-01
    学员管理系统函数的实际应用才能加深对函数的理解。建立一个关于学员的的增减删改的内容。系统功能界面先把信息放进去打印出来看一看有没有问题,美不美观,调整一下......
  • [编程基础] Python字符串替换笔记
    date:2021-08-1622:00:12+0800tags:-编程基础-PythonPython字符串替换笔记Python字符串替换笔记主要展示了如何在Python中替换字符串。Python中有以下......
  • TCP/IP 协议(10):TCP 协议一百问
    TCP/IP协议(10):TCP协议一百问​​杨领well的TCP/IP协议专栏​​TCP协议部分一直没有更新,是因为我不确定到底应该怎么来介绍TCP协议才能干货满满。最后我决定以Q&A......