在网络上,通信服务都是采用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. (入门SpringBoot)SpringBoot结合拦截器(七)

    SpringBoot拦截器: 拦截器还是照旧和springmvc一样: @Componentpublic class MyInterceptor implements HandlerIntercept ...

  2. Docker 限制容器资源

     默认情况下,容器没有资源的限制,它可以使用整个主机的所有资源.Dcoker提供了控制资源的方法,  多少内存,CPU,IO,都可以在docker run使用标志符来设置.   内存 Docker可以 ...

  3. Copy Records From One Data Block To Another Data Block In Oracle Forms

    In this tutorial you will learn to copy the records from one data block to another data block on sam ...

  4. 人生中的那口井 z

    有两个和尚住在隔壁,每天都会在同一时间下山去溪边挑水,不知不觉己经过了五年. 突然有一天,左边这座山的和尚没有下山挑水,过了一个星期,还是没有下山挑水. 直到过了一个月,右边那座山的和尚很担心就去探望 ...

  5. Windows Thin PC体验 & 语言包更改(win 7 included)

    本作品由Man_华创作,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可.基于http://www.cnblogs.com/manhua/上的作品创作. 简介: Window ...

  6. 【Android】getActionBar()为null的解决方法总结

    前言 在使用 ActionBar的时候,有时候会爆出空指针异常,这是由于应用没有获取到 ActionBar 导致的,而导致应用没有获取到 ActionBar 的原因比較多.所以我们以下就来总结一下 A ...

  7. nodejs初学-----helloworld

    近期紧锣密鼓的学习了下nodejs(之前在学php.算入门了吧,可是时间关系,还没写文章,兴许要搞安卓和大数据,总之比較忙哈,计划上php要排到后面了,还请广大小伙伴不要着急) 先抄一句:Node.j ...

  8. android 自己定义组件随着手指自己主动画圆

    首先自己定义一个View子类: package com.example.androidtest0.myView; import android.content.Context; import andr ...

  9. OS开发之旅之App的生命周期【转载】

    原文链接 http://www.360doc.com/content/15/0918/14/27799428_499912639.shtml 在iOS App中,入口函数并不在根目录下,而是在“Sup ...

  10. sphinx PDF 中文

    使用reST撰写文档时,需要分多个文档时,就必须使用sphinx了,sphinx说起来很简单的,但是默认是不是支持中文的.幸好我出生的晚,sphinx现在已经支持xelatex了^_^ 安装 除了pa ...