socket编程详解(一)——服务器端
写在前面(补充)
TCP/UDP对比
- TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前 不需 要建立连接
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
- TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) - 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- TCP首部开销20字节;UDP的首部开销小,只有8个字节
- TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
端口号作用
一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等
这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。
实际上是通过“IP地址+端口号”来区 分不同的服务的。
端口提供了一种访问通道,
服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69。
socket编程步骤
socket编程的总体流程如下图所示。 服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
服务器端编程的文字步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:绑定套接字到一个IP地址和一个端口上(bind());
3:将套接字设置为监听模式等待连接请求(listen());
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5:用返回的套接字和客户端进行通信(send()/recv()、read()/write());
6:返回,等待另一连接请求;
7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端编程的文字步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:向服务器发出连接请求(connect());
3:和服务器端进行通信(send()/recv());
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
接下来讲讲函数以及服务器端是怎么实现的。。。。
socket函数介绍
1、socket()函数
NAMEsocket - create an endpoint for communicationSYNOPSIS#include <sys/types.h> /* See NOTES */#include <sys/socket.h>
//原型int socket(int domain, int type, int protocol);DESCRIPTIONsocket() creates an endpoint for communication and returns adescriptor.//返回描述符
2、bind()函数
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>
//原型int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);//inet_aton()函数#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>int inet_aton(const char *cp, struct in_addr *inp);
//字节转换函数#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);
字节转换以及地址转换详细情况在字节序详细解读!!!
注:linux系统编程往往需要引用c头文件,linux下,头文件一般存储到/usr/include,如果找不到某些函数或者结构用法可以cd /usr/include/
比如我要找sockaddr_in结构用法:
cd /usr/include/
grep "struct sockaddr_in {" * -nir
//会有如下显示
linux/in.h:184:struct sockaddr_in {//定位184查看
vi linux/in.h +184
//结果
struct sockaddr_in {__kernel_sa_family_t sin_family; /* Address family */__be16 sin_port; /* Port number */struct in_addr sin_addr; /* Internet address
3、listen()函数
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>
//原型int listen(int sockfd, int backlog);
4、accept()函数
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>
//原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
在下面的demo中与之搭配的menset()函数,memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值。
cvoid *memset(void *s, int c, size_t n);
s指向要填充的内存块。
c是要被设置的值。
n是要被设置该值的字符数。
返回类型是一个指向存储区s的指针。
5、read、write函数
//read原型
ssize_t read(int fd, void *buf, size_t count);
//write原型ssize_t write(int fd, const void *buf, size_t count);
demo示例
server.c#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>int main(){int s_fd;struct sockaddr_in s_addr;struct sockaddr_in c_addr;char readBuf[128];char *msg = "I get your connection message";//void *memset(void *s, int c, size_t n);memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));//1.scoket//int socket(int domain, int type, int protocol);s_fd = socket(AF_INET,SOCK_STREAM,0);if(s_fd == -1){perror("socket");exit(-1);}s_addr.sin_family = AF_INET;s_addr.sin_port = htons(8089);inet_aton("192.168.2.40",&s_addr.sin_addr);//2.bind //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listen//int listen(int sockfd, int backlog);listen(s_fd,10);//4.accept//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);int len = sizeof(struct sockaddr_in);int c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&len);if(c_fd == -1){perror("accept");exit(-1); }printf("connect:%s\n",inet_ntoa(c_addr.sin_addr));//5.read//ssize_t read(int fd, void *buf, size_t count);int n_read = read(c_fd,readBuf,128);if(n_read == -1){perror("read");}else{printf("msg:%d,%s\n",n_read,readBuf);}//6.write//ssize_t write(int fd, const void *buf, size_t count);write(c_fd,msg,128);return 0;
}
目前服务器端代码比较鸡肋,期待后续文章。。。
执行步骤
gcc server.c -o server
./server打开Windows终端,ping是否可以成功,成功执行 telnet 192.168.2.xx(自己ipv4)端口号
结果如下图所示:
socket编程详解(一)——服务器端相关推荐
- PHP SOCKET编程详解
这篇文章主要介绍了PHP SOCKET编程详解,需要的朋友可以参考下 1. 预备知识 一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实 ...
- Linux的SOCKET编程详解
Linux的SOCKET编程详解 一. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统 ...
- Linux的SOCKET编程详解——非常叼
http://blog.csdn.net/hguisu/article/details/7445768/ 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Linux的SOCKE ...
- php里面的socket编程,详解PHP Socket 编程过程
详解PHP Socket 编程过程 作者:PHPYuan 时间:2019-03-13 03:41:20 概述 Socket用于进程间通信.进程间通信通常基于客户端-服务端模型.此时,客户端-服务端是可 ...
- Linux的SOCKET编程详解(转载)
一. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如: UN ...
- java 网络io详解_Java网络socket编程详解
或许有点长 但是一步步教你 我想你也愿意看7.2面向套接字编程 我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式7.2.1使用套接字实现基于 ...
- C# Socket 编程详解
Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和 System.Net.Sockets包含丰富的 ...
- Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
场景 Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article ...
- Java Socket编程详解
Java Socket编程是Java网络编程很重要的内容,现参考了许多资料,总结如下: 1. Java网络编程原理+Socket编程 http://www.cnblogs.com/linzheng/a ...
- C#Socket编程详解(一)TCP与UDP简介
一.TCP与UDP(转载) 1.TCP 1.1 定义 TCP(TransmissionControl Protocol)传输控制协议. 是一种可靠的.面向连接的协议(eg:打电话).传输效率低全双工通 ...
最新文章
- ASP.NET中EVAL用法大全
- 北京大力度建设城市绿道,我们身边处处是风景
- BZOJ4810: [Ynoi2017]由乃的玉米田
- idea调试怎么跳出循环_使用IDEA的Debug调试功能,查看程序的运行过程
- 律师如何加强自身的计算机文化教育网,提高_计算机文化基础_教学效果的几点心得.pdf...
- why object family error message is filtered out
- 手动编译 lombok_Lombok,一种编译时Java注释预处理器,可最大程度地减少代码大小...
- IDEA打开父类的接口方法快捷键
- 林斌首曝红米骁龙855旗舰新机:3200万像素弹出式前置摄像头
- React和Vue的模块化
- 【Espruino】NO.06 关键是你的仆人(继续)
- 数据库关于group by 两个或以上条件的分析
- DOOM启世录的启示
- android x5 webview 第一次,android:X5WebView 首次初始化 X5 内核耗时, 会产生卡顿现象的解决办法...
- PLSQL Developer使用
- 移远BC26使用总结
- 人脸识别功能实现的原理介绍与算法介绍
- NoteExpress中遇到的坑
- openwrt web框架luci简介,20行代码写一个前后端交互页面
- iOS11 API 更新整理