前提:本文基于Linux系统下的学习

服务器端

1 创建通讯端口,返回socket设备的文件描述符 sfd
socket(2)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建一个通讯端点
参数:
domain:
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7
type:
SOCK_STREAM:有序的 可靠的 双工的 基于连接的 字节流 tcp
SOCK_DGRAM: 基于数据包的 不可靠的 不需要连接的 udp
protocol:0
返回值:
成功 返回一个新的文件描述符
错误 -1 errno被设置

2 将sfd和服务器的地址和端口绑定
bind(2)
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:给一个socket绑定一个名字
参数:
sockfd:指定socket,有了地址家族,但没有具体的地址
addr: 指定具体的地址,根据地址家族采用具体的地址格式
addrlen:是addr所属结构体的字节数
返回值:
成功 0
错误 -1 errno被设置

socklen_t
struct sockaddr{
sa_family_t sa_family;
char sa_data[14];

}

ipv4 ipv6

3 将sfd设置为被动连接模式,监听客户端连接的到来.连接到来的时候,将连接放入一个未决连接队列中.listen(2)
int listen(int sockfd, int backlog);
功能:在指定的socket上监听连接
参数:
sockfd:指定要被监听的socket,必须是基于TCP的.
backlog:指定了未决连接队列的最大值
返回值:
成功 0
错误 -1 errno被设置

while(1){
4 从未决连接队列中取出一个连接进行处理,返回一个和客户端连接 的文件描述符cfd.阻塞 accept(2)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:从未决连接队列中获取第一个未决连接请求,创建一个连接socket.返回一个文件描述符cfd,使用这个cfd和客户端传输数据
参数:
sockfd:指定了在这个socket上获取第一个未决连接
addr:addr指定的地址空间里填充了客户端的地址.具体的格式取决于地址家族.如果为NULL,addrlen也被设置为NULL.
addrlen:指定了addr指向空间的大小
返回值:
错误 -1 errno被设置
成功 返回一个非负的文件描述符.处理的未决连接的的文件描述符
5 使用cfd读取客户端的请求信息 read(2)
6 处理客户端的请求信息
7 将处理结果回送给客户端 write(2)
8 关闭cfd close(2)
}

  1. #include <stdio.h>
  2. #include <sys/types.h> /* See NOTES */
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <string.h>
  6. int main(){
  7. char* msg="hector server..\n";
  8. char buf[];
  9. char IP[];
  10. struct sockaddr_in serv;//保存服务器的地址和端口
  11. struct sockaddr_in clie;//保存客户端的地址和端口
  12. socklen_t clie_len;
  13. //创建socket通讯端口,sfd
  14. int sfd=socket(AF_INET,SOCK_STREAM,);
  15. if(sfd==-){
  16. perror("socket");
  17. return -;
  18. }
  19. //初始化serv
  20. serv.sin_family=AF_INET;
  21. serv.sin_port=htons();
  22. serv.sin_addr.s_addr=htonl(INADDR_ANY);
  23. //将sfd绑定到到服务器
  24. int b=bind(sfd,(struct sockaddr*)&serv,sizeof(serv));
  25. if(b==-){
  26. perror("bind");
  27. return -;
  28. }
  29.  
  30. //设置为被动监听状态,将从客户端接收的连接放入未决连接中
  31. listen(sfd,);
  32. while(){
  33. clie_len=sizeof(clie);
  34. //未决连接为空,阻塞
  35. //不空,取出第一个连接并处理,cfd
  36. int cfd=accept(sfd,(struct sockaddr*)&clie,&clie_len);
  37. //客户端信息放到clie的地址空间
  38. printf("%s\n",inet_ntop(AF_INET,&clie.sin_addr,IP,));
  39.  
  40. //读取客户端的消息,显示出来
  41. int r=read(cfd,buf,);
  42. write(,buf,r);
  43. //响应客户端的信息
  44. write(cfd,msg,strlen(msg));
  45. close(cfd);
  46. }
  47.  
  48. return ;
  49. }

客户端
1 创建一个通讯端点.socket设备,返回该设备的文件描述符sfd
socket(2)
2 使用sfd连接到服务器.connect(2)
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:在socket上发起一个连接
参数:
sockfd:指定socket,在这个socket上发起一个连接请求
addr:指定了目标的地址.具体的格式取决于socket的地址家族
addlen:指定了addr的大小

返回值:
成功 0
错误 -1 errno被设置

3 向服务器发送信息
4 等待获取服务器的处理信息
5 将获取到的信息处理
6 告知服务器,关闭客户端的连接. close(2)

  1. #include <stdio.h>
  2. #include <sys/types.h> /* See NOTES */
  3. #include <sys/socket.h>
  4. #include <string.h>
  5. #include <arpa/inet.h>
  6. int main(){
  7. struct sockaddr_in serv;
  8. char buf[];
  9. char* msg="hector client\n";
  10. //创建socket通讯端口,sfd
  11. int sfd=socket(AF_INET,SOCK_STREAM,);
  12. if(sfd==-){
  13. perror("socket");
  14. return -;
  15. }
  16. //初始化serv成员
  17. serv.sin_family=AF_INET;
  18. serv.sin_port=htons();
  19. inet_pton(AF_INET,"127.0.0.1",&serv.sin_addr);
  20. //连接服务器
  21. int c=connect(sfd,(struct sockaddr *)&serv,sizeof(serv));
  22. if(c==-){
  23. perror("conncet");
  24. return -;
  25. }
  26. //向服务器发送消息
  27. write(sfd,msg,strlen(msg));
  28. //等待服务器的响应
  29. int r=read(sfd,buf,);
  30. write(,buf,r);
  31. //关闭
  32. close(sfd);
  33. return ;
  34. }

补充:

struct sockaddr 通用地址家族
{
sa_family_t sa_family;
char sa_data[14];
};

ipv4 地址家族
struct sockaddr_in {
sa_family_t sin_family; /*address family: AF_INET */
in_port_t sin_port; /*port in network byte order */
struct in_addr sin_addr; /* internet address */
};

/* Internet address. */
struct in_addr {
uint32_t s_addr;/*address in network byte order */
};

uint32_t ====== unsigned int

in_port_t======uint16_t======unsigned short int
端口需要网络字节序 大端
主机字节序 可能是大端,也可能是小端.

主机字节序=======>网络字节序
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

ip地址 192.168.1.4 点分十进制的格式 字符串 text
uint32_t binary
text<----->binary
inet_pton(3)
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
功能:text---->binary ipv4|ipv6
参数:
af:
AF_INET: ipv4 sin_addr

AF_INET6:ipv6

src:字符串格式的ip地址
dst:存放转换结果的首地址
返回值:
成功 1
src 无效 0
af 无效 -1 errno被设置

#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src,
char *dst, socklen_t size);
功能:binary----->text
参数:
af:
AF_INET: ipv4
AF_INET6:ipv6
src: binary格式的地址
dst: 存放转换结果的地址
size: 指定了dst可用空间的字节数
返回值:
错误 NULL errno被设置
成功 dst指向的地址

INADDR_ANY 代表本地的所有接口,所有的ip地址.

ipv6 地址家族

基于TCP的编程的更多相关文章

  1. 异常处理、socke基于TCP协议编程

    一.异常处理 1.错误和异常 1.程序中难免出现错误,而错误分成两种 (1)语法错误(这种错误过不了Python解释器的语法检测,必须在程序执行前改正) #语法错误示范一 if #语法错误示范二 de ...

  2. 异常处理、socket基于TCP协议编程

    一.异常处理 1.错误和异常 1.程序中难免出现错误,而错误分成两种 (1)语法错误(这种错误过不了Python解释器的语法检测,必须在程序执行前改正) #语法错误示范一 if #语法错误示范二 de ...

  3. 基于Socket网络编程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a2011480169/article/details/73602708 博客核心内容: 1.Sock ...

  4. 基于TCP的字符串传输程序

    ---恢复内容开始--- LINUX中的网络编程是通过SOCKET接口来进行的. Socket(套接字) Socket相当于进行网络通信两端的插座,只要对方的Socket和自己的Socket有通信联接 ...

  5. 基于TCP的网络编程

    HTTP协议,FTP协议等很多广泛应用的协议均基于TCP协议.TCP编程主要为C/S模式,客户端和服务器之间的程序设计存在较大差异. TCP编程框图 服务器调用socket().bind().list ...

  6. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

  7. JAVA基础知识之网络编程——-基于TCP通信的简单聊天室

    下面将基于TCP协议用JAVA写一个非常简单的聊天室程序, 聊天室具有以下功能, 在服务器端,可以接受客户端注册(用户名),可以显示注册成功的账户 在客户端,可以注册一个账号,并用这个账号发送信息 发 ...

  8. 基于TCP/IP协议的C++网络编程(API函数版)

    源代码:http://download.csdn.net/detail/nuptboyzhb/4169959 基于TCP/IP协议的网络编程 定义变量——获得WINSOCK版本——加载WINSOCK库 ...

  9. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

随机推荐

  1. MQ消息机制如何确认消费了消息?

    消息队列如何保证消息能百分百成功被消费 目前常用的消息队列有很多种,如RabbitMQ,ActiveMQ,Kafka...下面以RabbitMQ为例来讲如何保证消息队列中的信息能百分百被消费掉. 其中 ...

  2. 【mybatis源码学习】与spring整合Mapper接口执行原理

    一.重要的接口 org.mybatis.spring.mapper.MapperFactoryBean MapperScannerConfigurer会向spring中注册该bean,一个mapper ...

  3. 多层nginx中的压缩问题 api接口>1M数据的返回浏览器 网关

    基础 前端异步请求,局部刷新,加大最大等待时间 nginx开启压缩 进阶 多级nginx的压缩 实践测试: 每级都要开启压缩 gizp on: 最外层开启,但最内层没有开启 最外层没有开启 最外层.最 ...

  4. 001 centos7中的安装

    以前学习过centos6.4的安装使用,然后新使用centos7,发现有些修改配置变化了,记录一下. 1.修改主机名 查看主机名: 修改: 二:ip的固定 1.参考文章 https://www.jia ...

  5. 详解 C++11 lambda表达式

    详解 C++11 lambda表达式   lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的la ...

  6. bat函数调用 带返回值

    bat 脚本之 使用函数 摘自:https://blog.csdn.net/peng_cao/article/details/73999076 综述 bat函数写法 bat函数调用 bat函数返回值 ...

  7. Spring Boot系列之-helloword入门

    一. What: Spring Boot是什么?以1.4.3.RELEASE为例,官方介绍为:http://docs.spring.io/spring-boot/docs/1.4.3.RELEASE/ ...

  8. 使用Spring Boot接受HTTP GET/POST请求的一个SQL并返回结果

    这里说的意思是:我向我的Web服务器发送一个请求(因为GET请求的一些限制,所以最好使用POST请求,不过这里作为测试还是使用GET请求),请求中带一个sql参数,它对应查询的数据.然后我的Sprin ...

  9. kubernetes的几个概念

    1.  rc: 副本控制器,确保在任何时候都运行指定数量的pod副本.换句话说,ReplicationController确保一个pod或一组同构的pod始终处于可用状态. 2. rs:副本集,是rc ...

  10. 切实解决socket连接掉线检测

    原文:切实解决socket连接掉线检测 版权声明:欢迎转载,但是请保留出处说明 https://blog.csdn.net/lanwilliam/article/details/51698807 新公 ...