一、socket编程

   网络功能是Uinux/Linux的一个重要特点,有着悠久的历史,因此有一个非常固定的编程套路。

  基于TCP的网络编程:

    基于连接, 在交互过程中, 服务器和客户端要保持连接, 不能断开。重发一切出错数据、数据验证, 保证数据的正确性、完整性和顺序性,

    缺点是消耗的资源比较大。

  基于UDP的网络编程:

    无连接协议, 在网络交互过程中不保持连接, 只需要在发送数据时连接一下, 不重发、验证数据。优点是资源消耗少, 数据的可靠性完整性

    顺序性得不到保证。

二、编程步骤:

    服务器:

      ① 创建socket(套接字) socket()

      ② 准备通信地址

      ③ 将创建的socket和通信地址绑定 bind()

      ④ 监听端口 listen()

      ⑤ 等待客户端连接 accpet()

      ⑥ 通信双方收发数据 read()/write()

                 send()/recv()

      ⑦ 关闭socket

    客户端:

      ① 创建socket(套接字) socket()

      ② 准备通信地址

      ③ 连接服务器 connect()

      ④ 收发数据 read()/write()

             send()/recv()

      ⑤ 关闭socket  

三、API详解

  ① socket()函数

    int socket(domain, type, protocol)

    domain:

        AF_UNIX/AF_LOCAL/AF_FILE: 本地通信

        AF_INET: 网络通信 ipv4

        AF_INET6: 网络通信 ipv6

        注:如果AF换成PF效果一样

    type, 选择通信类型, 主要包括:

        SOCK_STREAM: TCP

        SOCK_DGRAM : UDP

    protocol, 本来应该指定通信协议, 但现在基本废弃, 因为协议已经在前面两个参数指定完成,给0即可

  ② bind()函数

    int bind(int sockfd, struct sockaddr *addr, size)

    sockfd: 要绑定的套接字描述符

    size: 第二个参数占据的内存空间大小

    addr: 涉及三个数据结构struct sockaddr, sockaddr_un, sockaddr_in

      sockaddr, 主要用于函数参数, 不负责存储数据

      sockaddr_un, 当着本地通信时, 用于本地通信使用的地址 (sys/un.h)

      sockaddr_in, 当着网络通信时, 负责存储网络通信的地址数据

      struct sockaddr_in {

          sin_family; //用于指定协议族, 和socket()的参数保持一致

          sin_port; //网络通信使用的端口号

          sin_addr; //存储网络通信的ip地址 

      }          

  ③ htons

  ④ inet_aton         

  ⑤ listen()函数

    int listen(int sockfd, int backlog)

     sockfd: 将sockfd参数所标识的套接字为被动模式, 使之可以接受连接请求

     backlog: 表示未决连接请求队列的最大长度, 即允许最多有多少个未决连接请求存在。若服务器的未决连接请求已达到该值, 则客户端通过 connect()连接服务器的操作将返回-1,且error为ECONNREFUSED

  ⑥ accpet()函数

    int accpet(sockfd, struct sockaddr* addr, socklen_t *addrlen)

     从sockfd参数所标识套接字对应未决连接请求队列中取出的一个连接请求, 同时创建一个新的套接字,用于该连接通信, 返回套接字的描述符

     addr和addrlen 用于输出连接请求发起者的地址信息

     返回值: 为新创建用于和客户端通信的套接字描述符 失败-1, error  

  ⑦ inet_ntoa

  ⑧ recv()函数  

   int recv(int sockfd, buf, len, flags)

     flags, 通常取0: 阻塞收取数据

        O_NONBLOCK: 不阻塞, 如果未收到数据, 返回错误信息

     返回值:

        >0, 实际接受数据字节数

        -1 , 出错, error

         0 , 通信的另一端关闭

  ⑨ send()函数

   int send(int sockfd, buf, len, flags)

     flags: 通常取0, 阻塞发送

     O_NONBLOCK: 不阻塞, 如果未收到数据, 返回错误信息

  ⑩ connect()函数

   int connect(int sockfd, addr, addr_len)

     参数参考bind()      

四、TCP示例

复制代码
1 /*******************************
2 client.c
3 ********************************/
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #define PORT 8888
13
14 int main()
15 {
16 /*1 创建socket*/
17 int sockfd = socket(AF_INET, SOCK_STREAM, 0);
18 if(sockfd == -1)
19 {
20 perror("socket failed");
21 exit(-1);
22 }
23 /*2 准备通信地址*/
24 struct sockaddr_in addr;
25 addr.sin_family = AF_INET;
26 /*设置为服务器进程的端口号*/
27 addr.sin_port = htons(PORT);
28 /*服务器所在主机IP地址*/
29 inet_aton("192.168.182.10", &addr.sin_addr);
30
31 /*3 连接服务器*/
32 int res = connect(sockfd,
33 (struct sockaddr *)&addr,
34 sizeof(addr));
35 if(res == -1)
36 {
37 perror("connect failed");
38 exit(-1);
39 }
40 printf("连接服务器成功....\n");
41 /*4 和服务器交换数据*/
42 char buf[100] = {0};
43 char *str = "借点钱可以吗...";
44 write(sockfd, str, strlen(str)) ;
45 read(sockfd, buf, sizeof(buf));
46 printf("服务器说:%s\n", buf);
47
48 /*关闭连接*/
49 close(sockfd);
50 return 0;
51 }
复制代码

复制代码
1 /************************************
2 server.c
3 *************************************/
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #define PORT 8888
14
15 int main()
16 {
17 /*1 创建socket*/
18 int sockfd = socket(AF_INET, SOCK_STREAM, 0);
19 if(sockfd == -1)
20 {
21 perror("socket failed");
22 exit(-1);
23 }
24 /*2 准备通信地址*/
25 struct sockaddr_in addr;
26 addr.sin_family = AF_INET;
27 addr.sin_port = htons(PORT);
28 inet_aton("192.168.182.10", &addr.sin_addr);
29
30 /*3 绑定socket和通信地址*/
31 int res = bind(sockfd,(struct sockaddr *)&addr,
32 sizeof(addr));
33 if(res == -1)
34 {
35 perror("bind failed");
36 exit(-1);
37 }
38 /*4 监听端口*/
39 res = listen(sockfd, 100);
40 if(res == -1)
41 {
42 perror("listen failed");
43 exit(-1);
44 }
45 printf("开始监听%d端口,等待客户端连接...\n",
46 PORT);
47 /*5 处理接收客户端的连接请求*/
48 //用于保存客户端地址信息
49 struct sockaddr_in fromaddr;
50 /*len 取0会是什么效果?*/
51 socklen_t len = sizeof(fromaddr);
52 int clientfd = accept(sockfd,
53 (struct sockaddr *)&fromaddr,
54 &len);
55 if(clientfd == -1)
56 {
57 perror("accept failed");
58 exit(-1);
59 }
60 printf("有一个客户端连接到服务器,它是:%s\n",
61 inet_ntoa(fromaddr.sin_addr));
62 /*6 处理客户端数据*/
63 char buf[100] = {0};
64 int count = recv(clientfd, buf, sizeof(buf),0);
65 printf("从客户端读取到%d字节:%s\n",
66 count, buf);
67 char *str = "欢迎你客户端";
68 send(clientfd, str, strlen(str), 0);
69 /*关闭连接*/
70 close(clientfd);
71 close(sockfd);
72 return 0;
73 }
复制代码
五、UDP示例

复制代码
1 /********************************
2 UDP_client.c
3 *********************************/
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12
13 #define PORT 12345
14 int main()
15 {
16 /*1 创建socket*/
17 int sd = socket(PF_INET, SOCK_DGRAM, 0);
18 if(sd == -1)
19 {
20 perror("socket failed");
21 exit(-1);
22 }
23 /*2 准备地址*/
24 struct sockaddr_in addr;
25 addr.sin_family = PF_INET;
26 addr.sin_port = htons(PORT);
27 inet_aton("192.168.182.10", &addr.sin_addr);
28 /*3 进行通信*/
29 char *str = "借点钱可以吗";
30 sendto(sd, str, strlen(str), 0,
31 (struct sockaddr *)&addr,
32 sizeof(addr));
33 char buf[100] = {0};
34 int len = sizeof(addr);
35 recvfrom(sd, buf, sizeof(buf), 0,
36 (struct sockaddr *) &addr,
37 &len);
38 printf("服务器说:%s\n", buf);
39 close(sd);
40 }
复制代码

复制代码
1 /********************************
2 UDP_server.c
3 *********************************/
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12
13 #define PORT 12345
14 int main()
15 {
16 /*1 创建socket*/
17 int sd = socket(PF_INET, SOCK_DGRAM, 0);
18 if(sd == -1)
19 {
20 perror("socket failed");
21 exit(-1);
22 }
23 /*2 准备地址*/
24 struct sockaddr_in addr;
25 addr.sin_family = PF_INET;
26 addr.sin_port = htons(PORT);
27 inet_aton("192.168.182.10", &addr.sin_addr);
28 /*3 socket addr 绑定*/
29 int res = bind(sd, (struct sockaddr *)&addr,
30 sizeof(addr));
31 if(res == -1)
32 {
33 perror("bind failed");
34 exit(-1);
35 }
36 /*4 进行通信*/
37 while(1)
38 {
39 char buf[100] = {0};
40 struct sockaddr_in fromaddr;
41 int len = sizeof(fromaddr);
42 recvfrom(sd, buf, sizeof(buf), 0,
43 (struct sockaddr *) &fromaddr,
44 &len);
45 printf("从客户端%s接收到数据:%s\n",
46 inet_ntoa(fromaddr.sin_addr),
47 buf);
48 char *str = "没问题,借多少";
49 sendto(sd, str, strlen(str), 0,
50 (struct sockaddr *)&fromaddr,
51 sizeof(fromaddr));
52 }
53 close(sd);
54
55 }

http://www.cnblogs.com/jiangson/p/5977601.html

Linux socket编程示例(最简单的TCP和UDP两个例子)的更多相关文章

  1. linux socket编程示例

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

  2. Linux Socket 编程简介

    在 TCP/IP 协议中,"IP地址 + TCP或UDP端口号" 可以唯一标识网络通讯中的一个进程,"IP地址+端口号" 就称为 socket.本文以一个简单的 ...

  3. Win Socket编程原理及简单实例

    [转]http://www.cnblogs.com/tornadomeet/archive/2012/04/11/2442140.html 使用Linux Socket做了小型的分布式,如Linux ...

  4. Linux socket 编程中存在的五个隐患

    前言:         Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是   开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它 ...

  5. Linux 下socket通信终极指南(附TCP、UDP完整代码)

    linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...

  6. 多线程Java Socket编程示例

    package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...

  7. 使用socket编程实现一个简单的文件服务器

    使用socket编程实现一个简单的文件服务器.客户端程序实现put功能(将一个文件从本地传到文件服务器)和get功能(从文件服务器取一远程文件存为本地文件).客户端和文件服务器不在同一台机器上. pu ...

  8. Java Socket编程示例

    一.Socket简介: 1.什么是Socket 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket ...

  9. C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性

    C/C++ socket编程教程之九:TCP的粘包问题以及数据的无边界性 上节我们讲到了socket缓冲区和数据的传递过程,可以看到数据的接收和发送是无关的,read()/recv() 函数不管数据发 ...

随机推荐

  1. POJ 1018 Communication System 贪心+枚举

    看题传送门:http://poj.org/problem?id=1018 题目大意: 某公司要建立一套通信系统,该通信系统需要n种设备,而每种设备分别可以有m个厂家提供生产,而每个厂家生产的同种设备都 ...

  2. 【Codeforces Round #440 (Div. 2) B】Maximum of Maximums of Minimums

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] k=1的时候就是最小值, k=2的时候,暴力枚举分割点. k=3的时候,最大值肯定能被"独立出来",则直接输出最 ...

  3. dp hdu5653 xiaoxin and his watermelon candy

    传送门:点击打开链接 题意:有n个箱子排成一排,有m个炸弹.位置告诉你.如今炸弹的左边伤害和右边伤害能够自己控制,要求 每一个炸弹炸的箱子数的累乘,输出答案取log2并乘以1e6 思路:直接2for ...

  4. storm-kafka编程指南

    目录 storm-kafka编程指南 一.原理及关键步骤介绍 (一)使用storm-kafka的关键步骤 1.创建ZkHosts 2.创建KafkaConfig 3.设置MultiScheme 4.创 ...

  5. complex query几个原则

    1.一般来说in比exists更有利(更容易变成join). 2.尽量避免union,使用union all代替,避免sort. 3,绝对不能在没有on条件下使用join(除非有特殊目的). 4.ou ...

  6. EJBCA在Linux上的安装

    在windows上安装为了測试用,装在linux服务器上的由于CN用的ip须要重装.....又是折腾一番,以下介绍一些须要注意的地方 一.所需文件 准备的内容就不说了,參考我的上上篇<EJBCA ...

  7. 终端中经常使用的shell 命令

    Mac 在shell命令终端中,Ctrl+n相当于方向向下的方向键,Ctrl+p相当于方向向上的方向键. 在命令终端中通过它们或者方向键能够实现对历史命令的高速查找.这也是高速输入命令的技巧. 在命令 ...

  8. Ubuntu snmp配置

    http://wenku.baidu.com/link?url=7ieAta_w87NDrTOT_DyEQSj4Rd9i82YRUGQl--g077oC3ftckgH7wpT5QEyir-NtZLA3 ...

  9. MVC4中AJAX Html页面打开调用后台方法实现动态载入数据库中的数据

    之前一直用window.onload方法来调用js方法来实现,今天纠结能不能换个方法实现. 非常明显是能够的. 在html前台页面引用js代码例如以下 @Scripts.Render("~/ ...

  10. MKNetworkKit的断点续传SIDownloader下载

    comefrom:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d6f8b9042238fce098 ...