本文中的TCP server 和 client,为基于软件层面(TCP/IP协议栈)的Socket应用开发。

一.Socket

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

数据结构:注意sockaddr_in 和 sockaddr的区别(前者具体,后者抽象)

#ifdef CONFIG_NET_IPv6
struct sockaddr_storage
{sa_family_t ss_family;       /* Address family */char        ss_data[18];     /* 18-bytes of address data */
};
#else
struct sockaddr_storage
{sa_family_t ss_family;       /* Address family */char        ss_data[14];     /* 14-bytes of address data */
};
#endif/* The sockaddr structure is used to define a socket address which is used* in the bind(), connect(), getpeername(), getsockname(), recvfrom(), and* sendto() functions.*///抽象的socket地址,不区分IPV4,IPV6
//14字节 = 2(端口) + 4(ip地址) + 8(保留)
struct sockaddr
{sa_family_t sa_family;       /* Address family: See AF_* definitions */char        sa_data[14];     /* 14-bytes of address data */
};//IPV4协议,将 2(端口) + 4(ip地址)分开表示
struct sockaddr_in
{sa_family_t     sin_family;  /* Address family: AF_INET */uint16_t        sin_port;    /* Port in network byte order */struct in_addr  sin_addr;    /* Internet address */
};//IPV6
struct sockaddr_in6
{sa_family_t     sin6_family; /* Address family: AF_INET6 */uint16_t        sin6_port;   /* Port in network byte order */struct in6_addr sin6_addr;   /* IPv6 internet address */
};

函数接口:

int socket(int domain, int type, int protocol);
int bind(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen);
int connect(int sockfd, FAR const struct sockaddr *addr, socklen_t addrlen);int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, FAR const void *buf, size_t len, int flags,FAR const struct sockaddr *to, socklen_t tolen);ssize_t recv(int sockfd, FAR void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,FAR struct sockaddr *from, FAR socklen_t *fromlen);

二.TCP 与 UDP

TCP(Transmission Control Protocol,传输控制协议是面向连接的,基于数据流的可靠协议,在正式通信之前必须建立起连接。UDP(User Data Protocol,用户数据报协议)是一个非连接的数据报协议。TCP的服务器模式比UDP的服务器模式多了listen,accept函数。TCP客户端比UDP客户端多了connect函数。

这里只谈TCP的客户端与服务器。

三.TCP server

TCP server的实现流程:

1、创建一个socket,用函数socket();

2、绑定IP地址、端口等信息到socket上,用函数bind();

3、开启监听,用函数listen();

4、接收客户端上来的连接,用函数accept();

5、收发数据,用函数send()和recv(),或者read()和write();

6、关闭网络连接;

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>#define SERVPORT 4444
#define BACKLOG 10
#define MAXDATASIZE 15int main() {struct sockaddr_in server_sockaddr;//声明服务器socket存储结构int sin_size,recvbytes;int sockfd,client_fd;//socket描述符char buf[MAXDATASIZE];//传输的数据//1.建立socket//AF_INET 表示IPV4//SOCK_STREAM 表示TCPif((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {perror("Socket");exit(1);}printf("Socket successful!,sockfd=%d\n",sockfd);//以sockaddt_in结构体填充socket信息server_sockaddr.sin_family         = AF_INET;//IPv4server_sockaddr.sin_port       = htons(SERVPORT);//端口server_sockaddr.sin_addr.s_addr  = INADDR_ANY;//本主机的任意IP都可以使用bzero(&(server_sockaddr.sin_zero),8);//保留的8字节置零//2.绑定 fd与 端口和地址if((bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))) < 0) {perror("bind");exit(-1);}printf("bind successful !\n");//3.监听if(listen(sockfd,BACKLOG) < 0) {perror("listen");exit(1);}printf("listening ... \n");while(1){//4.接收请求,函数在有客户端连接时返回一个客户端socket fd,否则则阻塞//优化:这里同样可以使用select,以及poll来实现异步通信if((client_fd = accept(sockfd,NULL,&sin_size)) == -1) {perror("accept");exit(1);}printf("accept success! client_fd:%d\n",client_fd);//5.接收数据//注意:这里传入的fd,不是建立的socket fd,而是accept返回的连接客户端 socket fdif((recvbytes = recv(client_fd,buf,MAXDATASIZE,0)) == -1) {perror("recv");exit(1);}printf("received data : %s\n",buf);}//6.关闭close(sockfd);}

四.TCP client

TCP client的实现流程:

1、创建一个socket,用函数socket();

2、连接服务器,用函数connect();

3、收发数据,用函数send()和recv(),或者read()和write();

4、关闭网络连接;

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>#define SERVPORT 4444int main(int argc,char *argv[]) {int sockfd,sendbytes;struct sockaddr_in serv_addr;//需要连接的服务器地址信息//1.创建socket//AF_INET 表示IPV4//SOCK_STREAM 表示TCPif((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) {perror("socket");exit(1);}//填充服务器地址信息serv_addr.sin_family     = AF_INET; //网络层的IP协议: IPV4serv_addr.sin_port      = htons(SERVPORT); //传输层的端口号serv_addr.sin_addr.s_addr   = inet_addr("192.168.1.xxx"); //网络层的IP地址: 实际的服务器IP地址bzero(&(serv_addr.sin_zero),8); //保留的8字节置零//2.发起对服务器的连接信息//三次握手,需要将sockaddr_in类型的数据结构强制转换为sockaddrif((connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))) < 0) {perror("connect failed!");exit(1);}printf("connect successful! \n");//3.发送消息给服务器端if((sendbytes = send(sockfd,"hello",5,0)) < 0) {perror("send");exit(1);}printf("send successful! %d \n",sendbytes);//4.关闭close(sockfd);}

以上是在 Linux(Ubuntu 18.04) 实现简单的TCP客户端与服务器的实例。

Linux C语言实现TCP客户端与服务器相关推荐

  1. C语言实现TCP客户端、服务器

    服务器 #include<stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include < ...

  2. TCP客户端显示服务器图片,TCP客户端显示服务器图片

    TCP客户端显示服务器图片 内容精选 换一换 ELB的常见异常返回码有400.403.502.504等.若遇到这些返回码建议您先直接访问后端云服务器,查看是否是后端云服务器的异常.若后端云服务器响应正 ...

  3. Qt开发的TCP客户端和服务器

    前言 自己写的demo测试程序,已通过网络调试助手验证程序是可行的,该程序界面可以切换TCP客户端和服务器,可以接收和发送信息到网络调试助手,可以切换不同的语言,项目下载地址:https://down ...

  4. linux epoll机制对TCP 客户端和服务端的监听C代码通用框架实现

    1 TCP简介 tcp是一种基于流的应用层协议,其"可靠的数据传输"实现的原理就是,"拥塞控制"的滑动窗口机制,该机制包含的算法主要有"慢启动&quo ...

  5. Python实现TCP客户端和服务器(多线程)

    收藏链接 服务端要做的事有这些: Step 1:创建ServerSocket对象,绑定监听的端口 Step 2:调用accept()方法监听客户端的请求 Step 3:连接建立后,通过输入流读取客户端 ...

  6. python实现TCP客户端从服务器下载文件

    TCP模拟服务器 import socketdef send_file_2_client(new_client_socket, client_addr):# 1. 接收客户端 需要下载的文件名# 接收 ...

  7. [Qt] TCP客户端与服务器断开连接自动重联机制

    TCP服务器断开连接自动重联机制 客户端加入定时器实现断线重联(客户端服务端代码见上一篇博客) 编译环境:Qt 5.9.5 ui界面如图: 代码如下 tcpclient.h #ifndef TCPCL ...

  8. linux使用nc命令模拟客户端与服务器,测试连通性

    首先需要安装netcap: mac 可以使用:brew install netcat centos可以参考:解决centos使用nc命令报错:Ncat: Connection refused. 测试连 ...

  9. c++ qt获取电脑的内存_Qt官方示例-TCP客户端/服务器示例

    该示例演示了在本地主机上的TCP客户端和服务器是如何通讯的. 客户端 绑定信号槽. connect(&tcpClient, &QAbstractSocket::connected, t ...

最新文章

  1. ESXi6.5环境搭建(五:常见问题及解决方案实验总结)
  2. 计算机反面的考研专业,2018计算机考研:历年准考证打印常见七大问题
  3. 链表list(链式存储结构实现)_数据结构知否知否系列之 — 线性表的顺序与链式存储篇(8000 多字长文)...
  4. python 读写函数
  5. 你不知道的127.0.0.1和0.0.0.0地址的区别
  6. 一个实用的显示Visual Studio Code文件绝对路径的扩展应用
  7. 【C单链表】链表与尾插法
  8. codevs 3287 货车运输 NOIP2013提高组
  9. [转]mysql_connect() 不支持 请检查 mysql 模块是否正确加载 解决
  10. Azure上部署FTP服务
  11. python定义私有变量的方法_Python中私有属性的定义方式
  12. JavaWeb笔记 黑马程序员课程
  13. HTML常用排版标签
  14. Fedora分区扩容以及如何修复引导
  15. “荣光医院”急救中心 73 问答
  16. Xbox 360抢鲜测评
  17. 爬虫与数据分析(二)
  18. Eclipse 自定义${date}变量格式的思路历程
  19. 6.2、C++的内联函数、函数重载、局部变量和全局变量
  20. 百度搜索の黑话大全—那些不为人知的搜索引擎语法

热门文章

  1. Discuz!教程之当插件、门户或自定义页面设置成首页时手机版访问跳转到forum.php?mobile=yes的问题
  2. python解除windows锁屏_用python获取win10锁屏图片
  3. 安防巡逻机器人在不同应用场景下的作用是什么?
  4. UVA 1600 Patrol Robot 巡逻机器人(BFS)
  5. 致我们渐行渐远的青春——给曾经的你
  6. kettle连接设置字符编码
  7. ABP入门系列之1——ABP总体介绍
  8. 000898先生的留言
  9. 要你命3000List30
  10. 【100%通过率】华为OD机试真题 Java 实现【猜字谜】【2022.11 Q4 新题】