uc第14天socket通信

 

回顾:
1。需要注意的一点:在Linux系统中,1024以下的端口只有拥有root权限的程序才能绑定,而且这些端口是给系统备用的,我们不可用。
线程
 信号量,条件变量
 互斥量和条件变量结合使用
 
socket
 本地通信,网络通信
 
本地通信
 使用socket文件进行进程间的通信
 1。创建socket :int sokfd=socket(int domain,int t,0) 函数
参数1:PF_UNIX,PF_LOCAL,PF_FILE  
   AF_UNIX,AF_LOCAL,AF_FILE
参数2:通信方式:SOCK_STREAM  流  SOCK_DGRAM报
 
 2。准备地址
#include <sys/un.h> 
struct sockaddr_un{
 xxx_family_t sun_family;//协议簇  本地:PF_UNIX类 
 char sun_path[];//本地通信使用的socke文件路径
};
 3。绑定
 bind(sockfd,(struct sockaddr*)&addr);
 4.通信
 其实际上就是文件的读写方式进行read/write
 5。关闭
 用关闭文件的方式进行关闭即可。
 
网络通信:
 1。创建socket
 int sockfd=socket{
  int dom,//AF_INET,PF_INET AF_INET6/PF_INET6
  int t,//SOCK_STREAM,SOCK_DGRAM
  0
 };
 2.准备网络通信地址(IP ,端口号)
 IP地址(找到计算机)/端口号(找到进程)
 #include <netinet/in.h>
 struct sockaddr_in {
  sa_family_t sin;//AF_INET,PF_INET AF_INET6..
  unsigned short sin_port;
  //这个不能直接赋值,需要用htons()转换为short htonl是转换为long类型
  即把主机字节和网络字节的转换。#include<arpa/inet.h>,为什么要作转换呢,因为每个主机上的int的存放有的是顺着放,有的是反着放。所以必须转换为统一的网络类型
  struct in_addr sin_addr;
  {
   in_addr_t s_addr;//unignet int;
   IP:192.168.0.23
  };//为什么要用结构体来表示ip地址了。是为了方便以后ip地址升级。
  inet_aton()函数可以把“192。168。0。23”转换为struct in_addr
  inet_ntoa()函数可以把struct in_addr转换为“192。168。0。23”
  inet_ator()函数可以把“192。168。0。23”转换为in_addr_t
 };
 
上课
网络7层协议(实际上没有用,实际用的是tcp/ip协议)
http ftp(应用层协议) 等是基于tcp/ip协议来实现的。(底层协议)
消息包的逐层递增,每一层都包装一下。
192.168.180.53
255.255.255.0
&与运算
192.168.180.0网络地址  (找到了同一网段):数据在同一网段内是广播出去的,只是你受到了我,而我丢弃了罢了。 我可以通过特殊的方式来不丢弃(黑客)
MAC地址:网卡物理地址
网络字节顺序
主机字节顺序
--------------------
TCP与UDP通信协议方式:
他们的区别:
 tcp:是面向连接的,可靠的传输协议,发出去的数据是不会丢失的。你没有收到我再给你发,没有收到我再发,直到你收到为止。因为他的通信方式是:首先要建立连接(3步握手)1。我发你2你说可以3我发落;
 udp:是无连接的,不可靠的传输协议。我想跟你发信息,我不跟你握手,也不通知你。我就猛发,数据分成一个一个小包,包丢了,我也不管。你也不知道。但是效率较高。因为他无需确认
 
用TCP进行通信
1。创建socket int sockfd=socket(PF_INET,SOCK_STREAM,0);
sock_stream表示用tcp协议,与第三个参数没有关系。流:先到先得
2。准备地址struct sockaddr_in同之前一样的
3。邦定同之前一样
4。监听,等这别人连接我呗。
linsten(int sockfd,int backlog//排队的最大长度,10表示只有10个人可以排队,1
1人就连接不上了)即阻塞对列长度:访问量过大时候需要你排队的长度

6。等待客户端连接:
int sockfd=accept(int sockfd,struct sockaddr* addr//保存客户端地址 socklen_t *addrlen//客户端地址的长度):阻塞函数:只要服务端一执行,就等待客户端访问
返回值:可以和客户端进行通信的socket描述符

监听客户端连接、等待客户端连接
 
socket可分2种方式 : 1对1 、 1对多(服务器和客户端)
服务器端有多个socket来对应客户端。每当有个客户端连接上来,那个监听的s主ocket就会与之连接,然后在创建出一个socket来于这个客户端进行连接。然后再断开主socket的联系。继续监听其他客户端的连接。

7。用新的socketfd和客户端进行通信。 

例子:tcpservice.c tcpclient.c
  timeservice.c timeclient.c
struct tm cur_tm* = localtime(&cur); 
 
如果每个服务都要几秒钟,多个客户端登录进来会感觉到很慢,为了使服务器能够为每个客户端同步的进行,而不是为了一个客户请求运行,导致其他客户阻塞。这样我们可以用多线程编程来解决这种感觉很慢的情况。 
 
聊天程序:
 服务器多线程:1。接收客户端的请求呗。(把客户端放到一个集合中去,只要这个集合里面有个客户端发信息过来,就把这个信息发送给每个客户端)
 客户端多线程:1。输入2。接收信息
 
 
 用UDP进行通信(重要的数据传输是不会使用UDP协议的)
 1。创建socket
 2.准备地址
 3。邦定
 4。通信
 5。关闭
 
UDP相对于TCP少了几个步骤:监听,无需连接
UDP使用的是sendto来发送信息,因为UDP无需连接,直接发送就是了。sendto中有个参数,表示要发送的地址。所以send需要连接这一步骤,sendto则无需。
UDP能否知道客户端是谁呢?如何拿到呢?即如何让服务器来给客户端来发送信息怎么办呢。
接收的时候,我们使用recvfrom来接收(多了参数),这样,就知道了。而使用recv就不得而知了。
只要服务器bind就可以了。
 

UC结束了。查!
src源程序
bin目标文件  子目录:config.xml
lib库文件
doc文档
include要被包含的头文件
思路好了可能会先写头文件、最好把网络通信代码,和业务逻辑代码分开。可能有以下头文件:
bank.h 在里面设置一些常量,全局变量。
service.h client.h bank.h socket.h manager.h ....

配置文件的写法:
#serice configuration
server_port=10222
server_ip=192.168.0.23

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值