socket 简介
对TCP/IP、UDP、Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵。那么我想问:
1. 什么是TCP/IP、UDP?
2. Socket在哪里呢?
3. Socket是什么呢?
4. 你会使用它们吗?
什么是TCP/IP、UDP?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
这里有一张图,表明了这些协议的关系。
图1
TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。
Socket在哪里呢?
在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。
图2
原来Socket在这里。
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
你会使用它们吗?
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。 生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。
图3
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
在这里我就举个简单的例子,我们走的是TCP协议这条路(见图2)。例子用MFC编写,运行的界面如下:
图4
图5
在客户端输入服务器端的IP地址和发送的数据,然后按发送按钮,服务器端接收到数据,然后回应客户端。客户端读取回应的数据,显示在界面上。
下面是接收数据和发送数据的函数:
int Receive(SOCKET fd,char *szText,int len)
{
int cnt;
int rc;
cnt=len;
while(cnt>0)
{
rc=recv(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}
int Send(SOCKET fd,char *szText,int len)
{
int cnt;
int rc;
cnt=len;
while(cnt>0)
{
rc=send(fd,szText,cnt,0);
if(rc==SOCKET_ERROR)
{
return -1;
}
if(rc==0)
return len-cnt;
szText+=rc;
cnt-=rc;
}
return len;
}
服务器端:
在服务器端,主要是启动Socket和监听线程。
#define DEFAULT_PORT 2000
void CServerDlg::OnStart()
{
sockaddr_in local;
DWORD dwThreadID = 0;
local.sin_family=AF_INET;
//设置的端口为DEFAULT_PORT。
local.sin_port=htons(DEFAULT_PORT);
//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。
local.sin_addr.S_un.S_addr=INADDR_ANY;
//初始化Socket
m_Listening = socket(AF_INET,SOCK_STREAM,0);
if(m_Listening == INVALID_SOCKET)
{
return ;
}
//将本地地址绑定到所创建的套接字上
if(bind(m_Listening,(LPSOCKADDR)&local,sizeof(local)) == SOCKET_ERROR )
{
closesocket(m_Listening);
return ;
}
//创建监听线程,这样也能响应界面上操作。
m_hListenThread = ::CreateThread(NULL,0,ListenThread,this,0,&dwThreadID);
m_StartBtn.EnableWindow(FALSE);
m_StopBtn.EnableWindow(TRUE);
}
监听线程函数:
DWORD WINAPI CServerDlg::ListenThread(LPVOID lpparam)
{
CServerDlg* pDlg = (CServerDlg*)lpparam;
if(pDlg == NULL)
return 0;
SOCKET Listening = pDlg->m_Listening;
//开始监听是否有客户端连接。
if(listen(Listening,40) == SOCKET_ERROR)
{
return 0;
}
char szBuf[MAX_PATH];
//初始化
memset(szBuf,0,MAX_PATH);
while(1)
{
SOCKET ConnectSocket;
sockaddr_in ClientAddr;
int nLen = sizeof(sockaddr);
//阻塞直到有客户端连接,不然多浪费CPU资源。
ConnectSocket = accept(Listening,(sockaddr*)&ClientAddr,&nLen);
//都到客户端的IP地址。
char *pAddrname = inet_ntoa(ClientAddr.sin_addr);
pDlg->Receive(ConnectSocket,szBuf,100);
//界面上显示请求数据。
pDlg->SetRequestText(szBuf);
strcat(szBuf," :我是老猫,收到(");
strcat(szBuf,pAddrname);
strcat(szBuf,")");
//向客户端发送回应数据
pDlg->Send(ConnectSocket,szBuf,100);
}
return 0;
}
服务器端一直在监听是否有客户端连接,如有连接,处理客户端的请求,给出回应,然后继续监听。
客户端:
客户端的发送函数:
#define DEFAULT_PORT 2000
void CClientDlg::OnSend()
{
DWORD dwIP = 0;
TCHAR szText[MAX_PATH];
memset(szText,0,MAX_PATH);
m_IP.GetWindowText(szText,MAX_PATH);
//把字符串形式的IP地址转成IN_ADDR结构需要的形式。
dwIP = inet_addr(szText);
m_RequestEdit.GetWindowText(szText,MAX_PATH);
sockaddr_in local;
SOCKET socketTmp;
//必须是AF_INET,表示该socket在Internet域中进行通信
local.sin_family=AF_INET;
//端口号
local.sin_port=htons(DEFAULT_PORT);
//服务器的IP地址。
local.sin_addr.S_un.S_addr=dwIP;
////初始化Socket
socketTmp=socket(AF_INET,SOCK_STREAM,0);
//连接服务器
if(connect(socketTmp,(LPSOCKADDR)&local,sizeof(local)) < 0)
{
closesocket(socketTmp);
MessageBox("连接服务器失败。");
return ;
}
//发送请求,为简单只发100字节,在服务器端也规定100字节。
Send(socketTmp,szText,100);
//读取服务器端返回的数据。
memset(szText,0,MAX_PATH);
//接收服务器端的回应。
Receive(socketTmp,szText,100);
TCHAR szMessage[MAX_PATH];
memset(szMessage,0,MAX_PATH);
strcat(szMessage,szText);
//界面上显示回应数据。
m_ReplyBtn.SetWindowText(szMessage);
closesocket(socketTmp);
}
客户端就一个函数完成了一次通信。在这里IP地址为何用127.0.0.1呢?使用这个IP地址,服务器端和客户端就能运行在同一台机器上,这样调试方便多了。当然你可以在你朋友的机器上运行Server程序(本人在局域网中测试过),在自己的机器上运行Client程序,当然输入的IP地址就该是你朋友机器的IP地址了。
简单的理论和实践都说了,现在Socket编程不神秘了吧?希望对你有些帮助。
(unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误(一个实际socket编程中遇到的问题,希望对你有帮助)
socket 简介的更多相关文章
- Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...
- 计算机网络(十二),Socket简介
目录 1.Socket简介 2.Socket工作原理 十二.Socket简介 1.Socket简介 2.Socket工作原理
- 网络编程(socket简介)
socket简介 Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中 ...
- Socket简介 与 UDP
1. Socket 简介 2. UDP 1. Socket 简介 网络编程,是指让在不同的电脑上的软件能够进行数据传递,即进程之间的通信. 本地的进程间通信(IPC) 例如有:队列.同步(互斥锁.条件 ...
- Socket简介 (转)
Socket小白篇-附加TCP/UDP简介 Socket 网络通信的要素 TCP和UDP Socket的通信流程图 1.Socket 什么是Socket Socket:又称作是套接字,网络上的两个程序 ...
- Socket简介
本文全部摘抄http://c.biancheng.net/cpp/html/3029.html 大多数项目是在Linux下开发服务器端,而在Windows下开发客户端,需要经常在两大平台之间进行切换, ...
- 网络编程2之Socket简介和java.net包
一.Socket 通信链路的端点就被称为"套接字"(英文名Socket) 是提供给应用程序的接口 图文说明Socket Socket通信原理 二.java.net包 Java.ne ...
- Unix domain socket 简介
Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信.socket 原本是为网络通讯设 ...
- iOS进阶_Socket(Socket简介&代码演练)
网络通讯三要素 TCP & UDP 三次握手 断开连接的四次握手 Socket套接字 了解了上面的概念,我们开始演练一下Socket #import "ViewController. ...
随机推荐
- 前端必须掌握30个CSS3选择器
也许你已经学会了CSS的三个简单常用的选择器:#ID,.class,标签选择器,可是这些就足够了吗?随着CSS3的到来,作为前端开发者需要掌握下面三十个基本的选择器,这样才可以在平时开发中得心用手. ...
- 【Noip2012】解题报告【字符】【贪心】【高精度】【倍增】【set】
目录:1:vigenere密码[字符]2:国王游戏[贪心][高精度]3:开车旅行[倍增][set] 题目: VJ P1778 vigenere密码 Accepted 标签:NOIP提高组2012 ...
- POJ 1741 树上的点分治
题目大意: 找到树上点对间距离不大于K的点对数 这是一道简单的练习点分治的题,注意的是为了防止点分治时出现最后分治出来一颗子树为一条直线,所以用递归的方法求出最合适的root点 #include &l ...
- Section 1.4 Packing Rectangles
本来是USACO Training的1.4.1的,但是介于今早过了食物链想起了这道题实在是太怨念了,翻出自己写的AC程序居然有5KB!! 思路很简单,枚举,而且就图中的六种情况.但是第六种变化状况太多 ...
- mysql中Access denied for user 'root'@'localhost' (using password:YES)(zhuan)
错误代码 1045Access denied for user 'root'@'localhost' (using password:YES) 如果你的mysql也出现以上这种提示, 建议你逐个字看完 ...
- [转]理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站)
理解 WSRF第1部分-使用 WS-ResourceProperties 本 教程是一个由 4 部分组成的系列文章中的第 1 部分,该系列介绍 WSRF(Web Services Resource ...
- MicroPython开发板TPYBoard关于USB-HID的应用
USB-HID是Human Interface Device的缩写,属于人机交互操作的设备,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球.电话拨号设备.VCR遥控等等设备. ...
- key 4v4
#include "key4v4.h" #include "stm32f10x.h" #include "delay.h" /* PA4-L ...
- 实例化(用new的方式)创建一个对象的顺序
父类静态块--->子类静态块----->父类普通代码块----->父类构造方法------->子类普通代码块----->子类构造方法 如果父类构造方法中调用的非priva ...
- 2013年8月份第1周51Aspx源码发布详情
校企工作室OA源码 2013-8-9 [VS2010]源码描述:主要模块及系统管理功能说明:一.考勤功能模块:考勤分成三个功能,显示签到功能,查询功能,管理功能.1.签到功能分析:在签到功能中,我们 ...