linux-网络编程-基于C语言

TCP/IP的四层模型

  • 网络接口层:负责将二进制流转换为数据帧,并进行数据帧的发送和接收。数据帧是网络信息传输的基本单元,ARP和RARP协议
  • 网络层:负责将数据帧封装成IP数据报,同时负责选择数据报的路径,即路由,IP和ICMP协议
  • 传输层:负责端到端之间的通信会话连接与建立,传输协议的选择根据数据传输方式而定,UDP和TCP协议
  • 应用层:负责应用程序的网络访问,这里通过端口号来识别各个不同的进程,FTP、TELNET、DNS、SMTP、POP3 协议

基于TCP协议的socket程序编程

传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。

基于TCP协议的socket的server端程序编程步骤:

  1. 建立socket ,使用socket()
  2. 绑定socket ,使用bind()
  3. 打开listening socket,使用listen()
  4. 等待client连接请求,使用accept()
  5. 收到连接请求,确定连接成功后,使用输入,输出函数recv(),send()与client端互传信息
  6. 关闭socket,使用close()

基于TCP协议的socket的Client程序编程步骤:

  1. 建立socket,使用socket()

  2. 通知server请求连接,使用connect()

  3. 若连接成功,就使用输入输出函数recv(),send()与server互传信息

  4. 关闭socket,使用close()

基于UDP协议的socket编程

UDP是无连接的、不可靠的数据协议报,而TCP是面向连接的,提供可靠的字节流。然而,有些情况下更适合用UDP而不是TCP。有些流行的应用程序是用UDP实现的:DNS(域名系统)、NFS(网络文件系统)和SNMP(简单网络管理协议)就是这样的例子。

基于UDP协议的socket的接收端编程步骤:

  1. 建立socket,使用socket()
  2. 绑定socket,使用bind()
  3. 以recvfrom()函数接收发送端传来的数据
  4. 关闭socket,使用close()

基于UDP协议的socket的发送端编程步骤:

  1. 建立Socket,使socket()
  2. 用sendto()函数向接收端发送数据。
  3. 关闭socket,使用close()函数

基于TCP协议的socket程序编程例程

tcp_server.c 实现tcp服务端的功能:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main( int argc, char **argv )
{
      int sid = socket(AF_INET,SOCK_STREAM,0);
      struct sockaddr_in addr = {0};
      addr.sin_family = AF_INET;
      addr.sin_port = htons(atoi(argv[2]));
	
      addr.sin_addr.s_addr = inet_addr(argv[1]);
      int res = bind(sid,(struct sockaddr *)&addr,sizeof(struct sockaddr));
      printf("bind res = %d\n",res);
      listen(sid,10);
	
      char buf[128] = {0};
      int len,cid;
	
      while(1)
      {
            cid = accept(sid,NULL,NULL);
            bzero(buf,sizeof(buf));
            while(strncmp(buf,"quit",4))
            {
                  bzero(buf,sizeof(buf));
                  read(cid,buf,sizeof(buf) - 1);
                  write(cid,buf,strlen(buf));
            }
            close(cid);
      }
      close(sid);
      return 0;
}

tcp_client.c , 实现tcp客户端的功能:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>

int main(int argc,char **argv)
{
      if(argc < 3)
      {
            perror("param must >= 3");
            return -1;
      }

      int cid = socket(AF_INET,SOCK_STREAM,0);
      struct sockaddr_in saddr = {0};
      saddr.sin_family = AF_INET;
      saddr.sin_port = htons(atoi(argv[2]));
      saddr.sin_addr.s_addr = inet_addr(argv[1]);

      int res = connect(cid,(struct sockaddr *)&saddr,sizeof(struct sockaddr));
      printf("connect res = %d\n",res);

      char buf[128] = {0};
      int len;
      while(strncmp(buf,"quit",4))
      {
            bzero(buf,sizeof(buf));
            fgets(buf,sizeof(buf),stdin);
            len = send(cid,buf,strlen(buf),0);
            printf("client send: len = %d\n",len);
		
            bzero(buf,sizeof(buf));
            recv(cid,buf,sizeof(buf) - 1,0);
            printf("client recv: buf = %s\n",buf);
      }
      close(cid);
      return 0;
}

基于UDP协议的socket程序编程例程

udp_recv.c, 实现udp数据接收的功能:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

int main(int argc,char **argv)
{
      if(argc < 3)
      {
            perror("param must >= 3");
            return -1;
      }

      int cid = socket(AF_INET,SOCK_DGRAM,0);
      if(cid < 0)
      {
            perror("socket error");
            return -1;
      }

      struct sockaddr_in addr = {0},sendaddr = {0};
      addr.sin_family = AF_INET;
      addr.sin_port = htons(atoi(argv[2]));
      addr.sin_addr.s_addr = inet_addr(argv[1]);

      int res = bind(cid,(struct sockaddr *)&addr,sizeof(struct sockaddr));
      printf("bind res = %d\n",res);

      char buf[128] = {0};
      int size = sizeof(struct sockaddr);
      int len = recvfrom(cid,buf,sizeof(buf) - 1,0,(struct sockaddr *)&sendaddr,&size);
      char ipbuf[16] = {0};
      inet_ntop(AF_INET,&sendaddr.sin_addr.s_addr,ipbuf,sizeof(ipbuf));
      printf("len = %d buf = %s\n",len,buf);
      printf("send addr: ip = %s,port = %d\n",ipbuf,ntohs(sendaddr.sin_port));

      close(cid);
      return 0;
}

udp_send.c , 实现udp数据发送的功能:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
      if(argc < 3)
      {
            perror("param must >= 3");
            return -1;
      }

      int cid = socket(AF_INET,SOCK_DGRAM,0);
      if(cid < 0)
      {
            perror("socket error");
            return -1;
      }

      struct sockaddr_in addr = {0};
      addr.sin_family = AF_INET;
      addr.sin_port = htons(atoi(argv[2]));
      addr.sin_addr.s_addr = inet_addr(argv[1]);

      char *str = "hello world";
      int len = sendto(cid,str,strlen(str),0,(struct sockaddr *)&addr,sizeof(struct sockaddr));
      printf("send len = %d\n",len);

      close(cid);
      return 0;
}
posted @ 2020-08-07 21:03  漫漫长夜何时休  阅读(231)  评论(0编辑  收藏  举报