套接字类型与协议设置

   我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息。type套接字类型里面的数据传输类型信息。protocol计算机通信中使用的协议信息。

协议族(Protocol Family)

协议族类型有:

    PE_INET          IPV4

    PE_INET6          IPV6

PF_LOCAL        本地通信的UNIX协议族

      PF_PACKET        底层套接字的协议族

PF_IPX         IPX Novell协议族

套接字类型(Type)

  套接字类型指的是套接字的数据传输方式,通过socket函数的第二个参数传递,只有这样才能决定创建的套接字的数据传输方式。决定了协议族并不能同时决定数据传输方式。也就是说socket函数第一个参数的PF_INET协议族存在多重数据传输方式。

第一种:面向连接的套接字(SOCK_STREAM)

  如果给第二个参数传递SOCK_STREAM,将创建面向连接的套接字。特点:

  • 套接字连接必须一一对性。
  • 可靠的、按序传递的、基于字节的面向连接的数据传输方式的套接字。

收发数据的套接字内部有缓冲(buffer),简言之就是字节数组。通过套接字传输的数据将保存到该数组中。因此,收到数据并不意味着马上调用read函数。只要不超过数组容量,则有可能数据填充满缓冲后通过一次read函数调用全部读完,也有可能分成多次调用read函数调用进行读取。也就是说,在面向连接的套接字中,read和write函数调用多次并无太大意义,所以说面向连接的套接字编程不存在数据边界。

如果套接字缓冲已满是否意味着数据丢失?首先调用read函数从缓冲区读取部分数据,因此,缓冲并不总是满的。但如果read函数读取的速度比接收数据的速度慢,则缓冲有可能被填满,此时套接字无法在接收数据,但即使这样也不会发生数据丢失。因为传输端套接字将停止传输。也就是说,面向连接的套接字会根据接收端的状态传输数据,如果传输出错还会提供重传服务。因此,面向连接的套接字除特殊的情况不会发生数据丢失。

第二种:面向消息的套接字(SOCK_DGRAM)

  如果给第二个参数传递SOCK_DGRAM,将创建面向消息的套接字。特点:

  • 不可靠的、不按序传递的、以数据的告诉传输为目的的套接字。
  • 传输的数据具有数据边界。

套接字协议信息

第三个参数主要用在同一协议族中存在多重传输方式相同的协议,数据传输方式相同,但协议不同。此时靠第三个参数具体指定协议信息。

简单的例子:

  要求在IPV4协议族中创建面向连接的套接字。其中在TCP/IP网络编程系列之一中创建服务端和客户端的代码,服务端的代码不需要改变,只改变客户端的代码,更改read函数的调用方式。

TCPClient代码

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

#define MAXSIZE 30
void Error_Handling(char* message);

int main(int argc,char* argv[])
{
    int sock;
    struct  sockaddr_in serverAddr;
    char message[MAXSIZE];
    int str_len=0;
    int idx=0,read_len=0;
    if(argc != 3)
    {
        printf("Usage : %s <IP> <Port> \n",argv[0]);
        exit(1);
    }
    sock = socket(PF_INET,SOCK_STREAM,0);
    if(sock == -1)
    {
        Error_Handling("sock() error");
    }
    memset(&serverAddr,0,sizeof(serverAddr));
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_addr.s_addr=inet_addr(argv[1]);
    serverAddr.sin_port=htons(atoi(argv[2]));
    if(connect(sock,(struct sockaddr*)&serverAddr,sizeof(serverAddr))==-1)
    {
        Error_Handling("connect() error");
    }
   
    while(( read_len = read(sock,&message[idx++],1)))
    {
        if(read_len==-1)
        {
            Error_Handling("read() error\n");
        }
        str_len+=read_len;
    }
    printf("Message from server : %s \n",message);
    printf("Function read call count:%d \n",str_len);
    close(sock);
    return 0;
}

void Error_Handling(char *message)
{
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

TCP/IP网络编程系列之二(初级)的更多相关文章

  1. TCP/IP网络编程系列之三(初级)

    TCP/IP网络编程系列之三-地址族与数据序列 分配给套接字的IP地址和端口 IP是Internet Protocol (网络协议)的简写,是为首发网络数据而分配给计算机的值.端口号并非赋予计算机值, ...

  2. TCP/IP网络编程系列之四(初级)

    TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的 ...

  3. TCP/IP网络编程系列之一(初级)

    概述 网络编程实际上就是编写程序使两台联网的计算机相互的交换数据.操作系统会提供名为“ 套接字 ”的部件.套接字是网络数据传输的软件设备,即使对网络数据传输原理不太熟悉也无关紧要.我们也能通过套接字完 ...

  4. TCP/IP网络编程之多进程服务端(二)

    信号处理 本章接上一章TCP/IP网络编程之多进程服务端(一),在上一章中,我们介绍了进程的创建和销毁,以及如何销毁僵尸进程.前面我们讲过,waitpid是非阻塞等待子进程销毁的函数,但有一个不好的缺 ...

  5. TCP/IP网络编程之多线程服务端的实现(二)

    线程存在的问题和临界区 上一章TCP/IP网络编程之多线程服务端的实现(一)的thread4.c中,我们发现多线程对同一变量进行加减,最后的结果居然不是我们预料之内的.其实,如果多执行几次程序,会发现 ...

  6. TCP/IP网络编程之优于select的epoll(二)

    基于epoll的回声服务端 在TCP/IP网络编程之优于select的epoll(一)这一章中,我们介绍了epoll的相关函数,接下来给出基于epoll的回声服务端示例. echo_epollserv ...

  7. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  8. 浅谈TCP/IP网络编程中socket的行为

    我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: 1. TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) 2. Socket I/O系统 ...

  9. TCP/IP网络编程之进程间通信

    进程间通信基本概念 进程间通信意味着两个不同进程间可以交换数据,为了完成这一点,操作系统中应提供两个进程可以同时访问的内存空间.但我们知道,进程具有完全独立的内存结构,就连通过fork函数创建的子进程 ...

随机推荐

  1. SqlServer中存储过程 returnC#代码处理以及对应的MySQL如何改写

    一.SqlServer 中 1. 创建表 create table testuser( id int, --primary key, names ), address ), paw ) ) 2.创建存 ...

  2. Winform 导航菜单的方法

    http://blog.163.com/kunkun0921@126/blog/static/169204332201171610619611/ 第一种:使用OutlookBar第三方控件 第二种:使 ...

  3. Redis--初入

    安装 .下载源码,解压缩后编译源码  $ wget http://download.redis.io/releases/redis-4.0.1.tar.gz $ tar xzf redis-4.0.1 ...

  4. CSS3 文本超出后显示省略号...

    纯用CSS实现,主要采用代码 overflow:hidden; text-overflow:ellipsis;//这是让文本溢出后,显示成省略号. white-space:nowrap;//禁止自动换 ...

  5. iOS 数组集合操作(交集,并集,差集,子集)

    1.求数组的 交集,并集,差集 NSArray *array1 = @[@"1",@"2",@"3"]; NSArray *array2 = ...

  6. 定位CPU高问题三把斧

    1.top -H -p PID 查看对应进程的哪个线程占用CPU过高 2.printf "%x\n" tid   将需要的线程ID转换为16进制格式 3.jstack pid &g ...

  7. Linux输入输出管理

      一.系统输入输出的理解 运行一个程序时,需要从某个位置读取输入信息,然后CPU处理,最后将输出 显示在屏幕或文件中:其中,某个位置相当于输入设备,屏幕或文件为输出设备. 标准输入:stdin,默认 ...

  8. Linux:grep命令详解

    grep grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具, ...

  9. linux给一个文件夹开启权限

    假如要给一个叫做xiaobang的文件夹权限,CD到这一级目录 chmod -R 777 xiaobang

  10. vue之element-ui设置全局弹出框

    这样的需求,在主要功能完成后,需要进行交互效果的完善,需要给请求api的时候添加一个加载中的一个弹出框.但是每个页面每个页面过的话,会很费时间和精力,这里我们可以采用element-ui中的服务式弹出 ...