在网络上,通信服务都是采用C/S机制,也就是客户端/服务器机制。流程可以参考下图:

服务器端工作流程:

使用socket()函数创建服务器端通信套接口

使用bind()函数将创建的套接口与服务器地址绑定

使用listen()函数使服务器套接口做好接收连接请求准备

使用accept()接收来自客户端由connect()函数发出的连接请求

根据连接请求建立连接后,使用send()函数发送数据,或者使用recv()函数接收数据

使用closesocket()函数关闭套接口(可以先用shutdown()函数先关闭读写通道)

客户端程序工作流程:

使用socket()函数创建客户端套接口

使用connect()函数发出也服务器建立连接的请求(调用前可以不用bind()端口号,由系统自动完成)

连接建立后使用send()函数发送数据,或使用recv()函数接收数据

使用closesocet()函数关闭套接口

下面介绍几个函数的用法:

socket函数:int
socket(int domain,int type,int protocol)

参数说明:
domain:指明协议族,也称为协议域,是一个常值。
AF_INET:IPv4
协议
AF_INET6:IPv6
协议
AF_LOCAL/AF_UNIX:Unix协议域
AF_ROUTE:
路由套接字
AF_KE:密匙套接字

type:指明套接字的类型。
SOCK_STREA:字节流套接字
SOCK_DGRA:数据报套接字
SOCK_SEQPACKE:有序分组套接字
SOCK_RAW:原始套接字

protocol:
指明协议类型。一般为0,以选择给定的domain和type组合的系统默认值。
IPPROTO_TCP:TCP传输协议
IPPROTO_UDP:UDP传输协议
IPPROTO_SCTP:SCTP传输协议

函数描述:
socket
函数在成功时返回一个小的非负整数值,与文件描述符类似,我们称它为套接字
描述符,简称
sockfd。为了得到这个套接字描述符,我们只是指定了协议族(IPv4、IPv6
或Unix)和套接字类型(字节流、数据报或原始套接字)。我们并没有指定本地跟远程的
协议地址

bind函数:int
bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

将一个本地协议地址赋予一个套接字。对于网际网协议,协议地址是32位的IPv4地址和128
位的IPv6地址与16位的TCP或UDP端口号的组合。bind
函数主要用于服务器端,用来指定本地
主机的哪个网络接口(IP,可以是INADDR_ANY,表示本地主机的任一网络接口)可以接受客户
端的请求,和指定端口号(即开启的等待客户来连接的进程)。

参数说明:

sockfd:
socket 函数返回的套接字描述符。

myaddr、addrlen:指向一个套接字地址结构的指针和该结构的大小。

地址结构的一般采用sockadr_in结构体

struct
sockaddr_in{

short
int sin_family; #地址族

unsigned
short int sin_port; #端口号

struct
n_addr sin_addr; #IP地址

unsigned
char sin_zeor[8]; #填充0保持与struct
sockaddr同样大小

}

listen函数:

int
listen(int sockfd,int backlog)

listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求。

Connetc函数:

connect函数的第一个参数即为客户端的socket描述字,第二参数为服务器的socket地址,第三个参数为socket地址的长度。客户端通过调用connect函数来建立与TCP服务器的连接

accept函数:

int
accept(int sockfd,struct sockaddr *addr, socketen_t *add_len)

参数sockfd
参数sockfd就是上面解释中的监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个一个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。
参数addr
这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址,当然这个地址是通过某个地址结构来描述的,用户应该知道这一个什么样的地址结构。如果对客户的地址不感兴趣,那么可以把这个值设置为NULL。
参数len
如同大家所认为的,它也是结果的参数,用来接受上述addr的结构的大小的,它指明addr结构所占有的字节个数。同样的,它也可以被设置为NULL。

如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信。

服务器测的代码如下:对于服务端来说,首先是建立socket然后绑定IP地址到socket上。然后开始监听。

当接收到请求的时候,通过recv函数存储在buf数组里面。并且通过send函数向对端发送消息

int server_function()
{
    char *sendbuf="thanks";
    char buf[256];
    int s_fd,c_fd;
    int s_len,c_len;
    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;
    s_fd=socket(AF_INET,SOCK_STREAM,0);
    s_addr.sin_family=AF_INET;
    s_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    s_addr.sin_port=PORT;
    s_len=sizeof(s_addr);
    bind(s_fd,(struct sockaddr *)&s_addr,s_len);
    listen(s_fd,10);
    while(1){
        printf("please wait a moment\n");
        c_len=sizeof(c_addr);
        c_fd=accept(s_fd,(struct sockaddr *)&c_addr,(socklen_t *__restrict)&c_len);
        recv(c_fd,buf,256,0);
        buf[strlen(buf)+1]='\0';
        printf("receve message:\n%s\n",buf);
        send(c_fd,sendbuf,strlen(sendbuf),0);
        close(c_fd);
    }
}

客户端的代码如下:设置好连接的IP地址和端口后,通过connect发起连接。并通过send和recv函数进行发送和接收消息

int client_function()
{
    char *buf="come on";
    char rebuf[250];
    int sockfd,len,newsockfd,len2;
    struct sockaddr_in addr;
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    addr.sin_port=PORT;
    len=sizeof(addr);
    newsockfd=connect(sockfd,(struct sockaddr *)&addr,len);
    len2=strlen(buf);
    send(sockfd,buf,len2,0);
    sleep(5);
    recv(sockfd,rebuf,40,0);
    printf("the length of the rebuf is %d",strlen(rebuf));
    rebuf[strlen(rebuf)+1]='\0';
    printf("receive message:\n%s\n",rebuf);
    close(sockfd);
    return 0;
}

打开2个终端,分别运行服务器和客户端的代码。执行结果如下:

linux c编程:网络编程的更多相关文章

  1. Linux下TCP网络编程与基于Windows下C#socket编程间通信

    一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使s ...

  2. 7)Linux程序设计入门--网络编程

    )Linux程序设计入门--网络编程 Linux系统的一个主要特点是他的网络功能非常强大.随着网络的日益普及,基于网络的 应用也将越来越多. 在这个网络时代,掌握了Linux的网络编程技术,将令每一个 ...

  3. Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)

    在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...

  4. Python编程-网络编程进阶(IO复用、Socketserver)

    一.认证客户端的链接合法性 如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加盐的方式来实现. 服务端 from socket import * imp ...

  5. Linux环境下网络编程杂谈《转》

    今天我们说说“Pre-网络编程”.内容比较杂,但都是在做网络应用程序开发过程中经常要遇到的问题. 一.大端.小端和网络字节序 小端字节序:little-endian,将低字节存放在内存的起始地址: 大 ...

  6. linux网络编程--网络编程的基本函数介绍与使用【转】

    本文转载自:http://blog.csdn.net/yusiguyuan/article/details/17538499 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览 ...

  7. Linux C高级编程——网络编程之以太网(2)

    Linux网络编程--以太网 宗旨:技术的学习是有限的,分享的精神是无限的. 1.以太网帧格式 源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的.用ifconf ...

  8. Linux C高级编程——网络编程基础(1)

    Linux高级编程--BSD socket的网络编程 宗旨:技术的学习是有限的,分享的精神是无限的. 一网络通信基础 TCP/IP协议簇基础:之所以称TCP/IP是一个协议簇,是由于TCP/IP包括T ...

  9. Linux下Socket网络编程

    什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...

  10. java socket编程(网络编程)

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...

随机推荐

  1. 2016集训测试赛(二十)Problem B: 字典树

    题目大意 你们自己感受一下原题的画风... 我怀疑出题人当年就是语文爆零的 下面复述一下出题人的意思: 操作1: 给你一个点集, 要你在trie上找到所有这样的点, 满足点集中存在某个点所表示的字符串 ...

  2. JVM中的内存分区简介

    1.JVM的内存区域划分: 大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) ...

  3. HDU2830

    一开始把题目意思理解错啦,做那好久没做出来.本题是一个dp问题:题目说列可以无限次对换,设矩阵为M[i][j],要找到面积大的矩形其实就是处理连续1的个数问题,用d[i][j](i表示行,j表示列)表 ...

  4. python的依赖性安全性检查

    1.safety 安装: pip install safety 使用: 检查整个系统的依赖包安全性safety check检查某个项目的依赖性安全safety check -r requirement ...

  5. 数据挖掘-MovieLens数据集_电影推荐_亲和性分析_Aprioro算法

    #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Tue Feb  7 14:38:33 201 ...

  6. JavaScript实现网页元素的拖拽效果

    以下的页面中放了两个div,能够通过鼠标拖拽这两个元素到任何位置. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamFja2ZydWVk/font/5a6 ...

  7. centos下lvs配置

    一.lvs-nat模式 网络配置: lvs-server eth0 :host-only adapter 192.168.56.101 lvs-server eth1 :Internal 192.16 ...

  8. struts2学习笔记2 -struts2的开发步骤和工作原理

    struts2的开发步骤: 1.先定义一个能发送请求的页面,可以是链接,也可以是表单(form) 2.开发action类,struts2对action并没有过多的要求,只要求: a 推荐实现actio ...

  9. 【Python】使用制表符换行符来添加空白

    在编程中,在打印时,有时候需要显示出来的数据看着舒服一点,那么使用制表符(\t).换行符(\n)即可轻松实现 >>> print('zhangsan')zhangsan 加入制表符后 ...

  10. 【Python】写入文件

    1.1写入空文件 若将文本写入文件,在调用open()时候需要提供另外一个实参,告诉Python你要写入打开的文件 file_path = 'txt\MyFavoriteFruit.txt' with ...