1.socket简介

在我们常用的网络通信中,socket是最常用的一种,socket编程也称套接字编程,下面我们将对socket编程进行相关讲解,其中包括服务器与客户端通信讲解,以及代码实现。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

2.socket网络通信步骤

在我们利用socket创建网络通信连接的时候,遵循下图所示的步骤:

图  1

图  2

如图1所示,当我们两台PC进行通信时,一方的服务器端server向另一方的客户端client发送数据时,由socket创建网络通道,但必须指定双方所使用的协议种类及端口号,同时还需告知IP地址。

其中IP地址相当于住址,用于查找PC所在的位置,端口号相当于“房间号”,用与告知通信双方所使用的端口,常用的通信协议由TCP/UDP两种,下面将补充介绍:

TCP/UDP协议对比:

1.TCP是面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。

2.TCP提供可靠的服务。也就是说TCP连接传送的数据无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。

3.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低。

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互式通信

5.TCP首部开销20字节;UDP的首部开销小,只有8字节。

6.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

如图2所示,在服务器端,首先新建一个socket套接字,同时绑定地址及端口号,这时进入监听状态,客户端此时若想连接服务器端,则发出连接请求,待服务器端接收请求后,一条完整的通信方式就建立完成,客户端和服务器便可进行数据交换了。

3.相关API介绍

创建套接字int socket(int domain,int type,int protocol),其中domain指明所使用的协议族,通常使用的因特网域为IPv4,设置为AF_INET。type为参数指定socket的类型,我们使用的为TCP协议,可以保证数据传输的正确性与顺序性,因此第二个参数设置为SOCK_STREAM。potocol通常赋值为“0”,0选择type类型对应的默认协议。返回值:若成功则返回socket套接字的文件描述符,若失败则返回-1.

IP与端口号绑定int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen),参数说明:sockfd为socket返回的描述符,addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针。其中第二个参数addr给出的结构体如下:

            struct sockaddr {sa_family_t sa_family;char        sa_data[14];}

结构体中的成员,sa_data[ ]表示进程地址;而bind函数中的第三个参数addrlen表示参数addr的长度;addr参数可以接受多种类型的结构体,而这些结构体的长度各不相同,因此需要使用addrlen参数额外指定结构体长度;经常为了传输IPv4的地址及端口号,定义一个struct sockaddr_in类型的结构体,但最后使用bind函数时必须转换成struct sockaddr *类型的。struct sockaddr_in如下:

struct sockaddr_in{sa_family_t sin_family;//协议族in_port_t sin_port;//端口号struct in_addr sin_addr;//IP地址结构体unsigned char sin_zero[8]://填充,没有实际意义
}

注意,在本结构体的第三个成员,相当于结构体的成员为结构体,注意结构体成员的引用。

地址转换int inet_aton(const char *straddr,struct in_addr *addrp);该函数的作用是将字符串形式的IP地址如“192.168.0.0.1”转换成网络能识别的形式,第一个参数straddr为IP地址字符串,第二个参数为struct in_addr *型数据,因此保持类型一致,我们首先给struct sockaddr_in中的第三个成员结构体给出IP地址,此时的类型刚好为struct in_addr类型,但要求的是结构体指针,我们只需进行取地址运算即可。

cha *inet_ntoa(struct in_addr inaddr)该函数的作用是将网络格式的IP地址转换成字符串格式,通常用于接收方接收对方的IP地址并转换为字符串形式。

监听int listen(int sockfd,int backlog);该函数只用于服务器端不断等待客户端的连接请求,第一个参数为描述符,第二个参数backlog指定在请求队列中允许的最大请求数。

接收连接int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);该函数用于接受客户端请求的连接。第一个参数为描述符,第二个参数addr用来返回已连接的客户端的协议地址,第三个参数addrlen为客户端地址长度。

请求连接int connect(int sockfd,const struct sockaddr *addr,socklen_t *addrlen)该函数用于客户端请求连接服务器端的函数,sockfd为描述符,addr为服务器端的IP地址和端口号的地址结构指针,addrlen为地址长度。

服务器端代码如下:

#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include<stdlib.h>
#include<string.h>int main(int argc,char **argv)
{int s_fd;int c_fd;int n_read;char readBuf[128];char msg[128]={0};struct sockaddr_in s_addr;struct sockaddr_in c_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));//1.sockets_fd=socket(AF_INET,SOCK_STREAM,0);if(s_fd==-1){perror("socket");exit(-1);}//2.binds_addr.sin_family=AF_INET;s_addr.sin_port=htons(atoi(argv[2]));inet_aton(argv[1],&s_addr.sin_addr);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listenlisten(s_fd,10);//4.acceptint c_len=sizeof(struct sockaddr_in);while(1){c_fd=accept(s_fd,(struct sockaddr *)&c_addr,&c_len);if(c_fd==-1){perror("accept");}printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));//5.readif(fork() == 0){if(fork()==0){while(1){memset(msg,0,sizeof(msg));printf("input \n:");gets(msg);write(c_fd,msg,strlen(msg));sleep(1);}}while(1){memset(readBuf,0,sizeof(readBuf));n_read=read(c_fd,readBuf,128);if(n_read==-1){perror("read");}else{printf("get message %d:%s\n ",n_read,readBuf);}}}}return 0;
}

在服务器端,当我们与客户端连接成功后,我们开辟一个子进程用来不断地读取客户端发送过来的消息并打印,与此同时再开辟一个子进程用来检测用户的输入,实现可以将服务器端的消息发送给客户端。

客户端代码:

#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include<stdlib.h>
#include<string.h>int main(int argc,char **argv)
{int c_fd;int n_read;char readBuf[128];char msg[128]={0};struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));//1.socketc_fd=socket(AF_INET,SOCK_STREAM,0);if(c_fd==-1){perror("socket");exit(-1);}//2.connectc_addr.sin_family=AF_INET;c_addr.sin_port=htons(atoi(argv[2]));inet_aton(argv[1],&c_addr.sin_addr);if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr))==-1){perror("connect");exit(-1);}printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));while(1){//3.sendif(fork()==0){while(1){memset(msg,0,sizeof(msg));printf("input \n:");gets(msg);write(c_fd,msg,strlen(msg));sleep(2);}}//4.readwhile(1){memset(readBuf,0,sizeof(readBuf));n_read=read(c_fd,readBuf,128);if(n_read==-1){perror("read");}else{printf("get message %d:%s\n ",n_read,readBuf);}}}return 0;
}

与服务器端不同,当我们请求连接成功后,便开辟子进程与服务器间进行通信。

Linux C 下的socket网络编程相关推荐

  1. Linux与Windows下的socket网络编程对比

    阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量.文章设置为仅粉丝可见,是因为写博客确实花了不少精力.希望互相进步谢谢!! 文章目录 阅读前请看一下:我是一个热衷于记 ...

  2. Linux操作系统下C语言网络编程(全文23475字,包含了Linux系统下所有网络编程的知识点,附程序代码)

    一.简介 如今网络应用随处可见,web.http.email 等这些都是网络应用程序,他们都有着基于相同的基本编程模型,有着相似的整体逻辑结构,并且还有着相同的编程接口.我们需要了解基本的客户端-服务 ...

  3. linux下C语言socket网络编程简例

    转自博文:http://blog.csdn.net/kikilizhm/article/details/7858405 在练习写网络编程时,该例给了我帮助,在写服务器时,我把while逻辑位置想法错了 ...

  4. Linux C++/Java/Web/OC Socket网络编程

    一,Linux C++ Socket网络编程 1.什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制 ...

  5. 5.3linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...

  6. 基于Linux的socket网络编程项目——游侠手机商城

    基于Linux的socket网络编程项目--游侠手机商城 一.项目说明 二.项目使用的技术 三.客户端搭建 四.服务器端搭建 一.项目说明 本项目是一个仿真手机商城类系统,基本功能: 登录界面功能:用 ...

  7. Linux 网络编程——socket 网络编程

    文章目录 一.网络基础 TCP/UDP对比 TCP/IP协议族体系 socket IP地址 IP地址转化API inet_addr() inet_aton() inet_ntoa() inet_pto ...

  8. 【Linux】socket网络编程之服务器与客户端的数据交互

    [Linux]socket网络编程之服务器与客户端的数据交互 前言参考 argc !=2是什么意思 inet pton函数 对stdin,stdout 和STDOUT_FILENO,STDIN_FIL ...

  9. Linux Kernel TCP/IP Stack — Socket Layer — TCP/UDP Socket 网络编程

    目录 文章目录 目录 TCP/UDP Socket 逻辑架构 创建 Socket 绑定 Socket 请求建立 Socket 连接 监听 Socket 接受请求 关闭连接 数据的发送和接收 send ...

  10. 【linux高级程序设计】(第十三章)Linux Socket网络编程基础 2

    BSD Socket网络编程API 创建socket对象 int socket (int __domain, int __type, int __protocol) :成功返回socket文件描述符, ...

最新文章

  1. 转 [JAVA] 使用 common-fileupload 实现文件上传
  2. pidstat 命令详解(转载)
  3. 电脑卡顿不流畅怎么解决_如何解决因电脑内存容量不足引起的卡顿?
  4. 「分块系列」数列分块入门3 解题报告
  5. php 分类代码,php无限分类的图文代码介绍
  6. QQ炫舞登录完后服务器没显示,qq炫舞进入界面后就没有了怎么回?
  7. CSS三大特性的利用注意事项
  8. iOS 应用取消时间栏
  9. 机器学习之推荐算法分类
  10. java异步编程的面试_去年去阿里面试,被问到java 多线程,我是这样手撕面试官的...
  11. 动画练习-360度旋转-animation
  12. 错误Access-Control-Allow-Origin原因及解决方法
  13. jquery 遍历java对象,js/jquery遍历对象和数组的方法分析【forEach,map与each方法】...
  14. 【181126】VC++开发的GIS系统源码无错完整版源代码
  15. 用Photoshop画气泡
  16. python对财务的作用知乎_Python与财务「上」——数据采集篇
  17. 03 数学软件与建模---微分方程建模
  18. javascript输入某年月某日,判断是这一年的多少天
  19. ICPC 2020 亚洲区域赛济南站 赛后总结
  20. 手绘计算机比赛海报,手绘海报大赛专题计划.doc

热门文章

  1. Maven dependency plugin使用
  2. 国家信息安全漏洞库最新动态发布,墨云科技成为CNNVD技术支撑单位
  3. 暴雪:星际2仍在审批 筹划中国电竞联赛
  4. catia逆向建模步骤_catia逆向工程应用
  5. 三菱plc编程有c语言吗,三菱plc编程用什么语言
  6. 软件需求说明书模板和实际案例
  7. 微星MSI电脑(GL63 8RE-416CN)打开BIOS隐藏的高级设置方法
  8. Java开源框架 iBase4J 搭建笔记
  9. Win10开启IPv6
  10. 2021接力题典1800【数学一】-汤家凤【题目册】