Socket也叫套接字,用来实现网络通讯,通过调用系统提供的API,可以和远程的机子传输数据。Socket有很多种协议,而这篇文章主要讨论TCP部分的内容,也就是说后面说的内容主要是指TCP Socket。

Socket 的一般调用过程:

服务端:socket(), bind(),listen(),accept(),send(),recv(),close()

客户端:socket(),connect(),send(),recv(),close()

阻塞socket(同步socket)

进程或线程执行到某些socket函数时必须等待该socket事件的发生,如果该事件没有发生,socket函数不能立即返回,进程或线程被阻塞。

特点:使用简单,适合一对一的应答场合,在服务端很少使用,或配合多线程使用

函数 返回值说明 阻塞情况
accept() 返回新的连接socket句柄。 缓冲区队列没有新的等待连接
connect() 返回-1说明连接失败,其他正常。 连接过程阻塞。
recv() 返回值小于1代表接收失败,其他代表接收数据的长度。 发送缓冲区有数据等待发送完成,或接收缓冲区没数据时阻塞。
send() 返回-1代表发送失败,其他为发送数据的长度 发送缓冲区没有足够空间保存此次发送数据时阻塞

非阻塞socket(异步socket)

进程或线程执行socket函数时不必非要等待该socket事件的发生,一旦执行立即返回。根据返回值的不同可以判断函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程可以不被阻塞,继续执行。

特点:函数执行立即返回,不会阻断进程,性能比阻塞高,适合在主线程直接调用,不会造成主线程卡顿现象

因为socket默认是阻塞的,所以要设置非阻塞模式:

#ifdef WIN32
DWORD nMode = 1;
ioctlsocket(m_sock, FIONBIO, &nMode);
#else
int r = fcntl(fd, F_GETFL, 0));
fcntl(fd, F_SETFL, r|O_NONBLOCK);
#endif

TCP与UDP 的区别


协议说明 socket创建
TCP 传输控制协议,可靠的连接服务。双方先建立连接再传输数据。提供超时重发,数据检验,流量控制等机制,保证数据发送无误。 socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
UDP 用户数据报协议,不可靠的连接服务。没有建立连接就可以发送数据,没有超时重发机制,传输速度很快。 socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)

Socket例子

下面以一个简单例子来说明服务端与客户端的交互过程

服务端 server.cpp

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") #define PORT 8080 int main()
{
//初始化winsock服务
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData); //创建socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in svraddr;
svraddr.sin_family = AF_INET;
svraddr.sin_port = htons(PORT);
svraddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定socket
bind(sock, (struct sockaddr*)&svraddr, sizeof(svraddr)); //监听socket
listen(sock, 5); while(1)
{
struct sockaddr_in addr;
int len = sizeof(SOCKADDR); char buf[1024] = {0}; //接受客户端连接
SOCKET client = accept(sock, (struct sockaddr*)&addr, &len); char* ip = inet_ntoa(addr.sin_addr);
printf("accept client: %s\r\n", ip); //接收客户端数据
if(recv(client, buf, 1024, 0) >0)
{
printf("recv client: %s\r\n", buf); //向客户端发送数据
send(client, "hello, client", strlen("hello, client"), 0);
}
closesocket(client);
} //关闭socket
closesocket(sock); //关闭winsock服务
WSACleanup(); return 0;
}

客户端 client.cpp

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") #define REMOTE_IP "127.0.0.1"
#define REMOTE_PORT 8080 int main()
{
//初始化winsock服务
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData); //创建socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in svraddr;
svraddr.sin_family = AF_INET;
svraddr.sin_port = htons(REMOTE_PORT);
svraddr.sin_addr.s_addr = inet_addr(REMOTE_IP); //连接socket
if( connect(sock, (struct sockaddr*)&svraddr, sizeof(svraddr)) != -1)
{
//发送数据给服务端
if(send(sock, "hello, server", strlen("hello, server"), 0) != -1)
{
//接收服务端数据
char buf[1024] = {0};
if(recv(sock, buf, 1024, 0) >0)
{
printf("recv server: %s\r\n", buf);
} }
}
else
{
printf("can not connect server\r\n");
} //关闭socket
closesocket(sock); //关闭winsock服务
WSACleanup();
getchar();
return 0;
}

基于TCP的socket通信过程及例子的更多相关文章

  1. 基于TCP协议Socket通信

    服务器线程处理类 package demo4; import java.io.*; import java.net.Socket; /** * 服务器线程处理类 * @ClassName Server ...

  2. IOS 基于TCP的socket通信详解(原创)

    最近在整理通信层相关知识,这篇文章是边整理边写的,有些地方可能不够准确,还请各位路过的大牛专家指出来.这次整理的socket通信是基于TCP的,实现方式是GCD形式,以下记录的都是些理论知识,方便自己 ...

  3. 基于tcp的socket通信

    # socket # socekt是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它 # 把复杂的tcp/ip协议族隐藏在socket接 ...

  4. python 之网络编程(基于TCP协议Socket通信的粘包问题及解决)

    8.4 粘包问题 粘包问题发生的原因: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包),这样接收端,就难于分辨出来了,必须提供科学的拆包机制. ...

  5. 一个基于tcp的socket简单对话小例子

    首先我们需要写连个py文件,一个server,一个client. import socket sk = socket.socket() # sk.bind(('ip',port)) sk.bind(( ...

  6. Java Web 基础(一) 基于TCP的Socket网络编程

    一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...

  7. Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

    Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...

  8. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

  9. 事件驱动的TCP协议Socket通信

    事件驱动的TCP协议Socket通信 介绍 常规的Socket通信案例一般都是在某个线程中建立连接,然后用一个while(true)循环判断是或否有数据传输,但是这种方法有局限性. 1.收到消息在处理 ...

随机推荐

  1. STUN/TURN/ICE协议在P2P SIP中的应用(二)

    1       说明 2       打洞和穿越的概念... 1 3       P2P中的打洞和穿越... 2 4       使用STUN系列 协议穿越的特点... 2 5       STUN/ ...

  2. boost::xml——基本操作以及中文乱码解决方案 (续)

    本博文主要想说明以下两点: 1.对于上一篇的<boost::xml——基本操作以及中文乱码解决方案>解释,这篇博文基本解决了正确输入输出中英文问题,但是好像还没有解决修改中文出现乱码的问题 ...

  3. JavaScript 输入自动完成插件

    作为web开发的一员,应该都不陌生,信息处理时,很多时候需要根据用户的输入实时反馈查询结果供其选择,这给了用户很好的人机交互体验,在各大门户网站上已经被使用的很成熟了,最近项目中用到此功能,网上有很多 ...

  4. 零售POS开发

    零售POS系统是一款基于离线与在线两种模式的POS系统,能够将门店的销售数据及时准确的同步到企业服务器.离线模式操作更加快捷.稳定.高效:在线操作实时同步会员信息.查看库存.下载最新档案.公文公告等一 ...

  5. jQuery提供的小方法

    jQuery提供的小方法: 1.选择器 + 事件 + 函数 = 复杂的交互 2.循环处理与选择器匹配的各个元素:each() $("#").each(function(){     ...

  6. 求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法

    原理 数据结构 // GO private static Map<Map<Integer,String>,Integer> GO = new HashMap<Map< ...

  7. JavaScript学习心得(二)

    一选择DOCTYPE DOCTYPE是一种标准通用标记语言的文档类型声明,目的是告诉标准通用标记语言解析器使用什么样的文档类型定义(DTD)来解析文档. 网页从DOCTYPE开始,即<!DOCT ...

  8. 【pyhton】短路逻辑

    编程语言常用的逻辑if a and b:#如果a是false,那么跳过b的判断,结果直接falseif a or b:#如果a为true,那么跳过b的判断,直接true

  9. Python资源汇集

    Python资源汇集 一 实用教程 廖雪峰网站 第一,Python教程:提供了循序渐进,重点是可操作的实用教程. 第二,Web App 项目教程.给出一个用16天完成的Python Web APP项目 ...

  10. 如何设置路由器实现静态IP配置

    一.概述 嵌入式开发者,经常面对这样的环境:PC(windows)+虚拟机(linux)+开发板.我们希望三者都能相互通信,而且可以联网. 对于实验室只提供一根网线,而自己没有额外的增加端口数量的设备 ...