基于TCP的socket通信过程及例子
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通信过程及例子的更多相关文章
- 基于TCP协议Socket通信
服务器线程处理类 package demo4; import java.io.*; import java.net.Socket; /** * 服务器线程处理类 * @ClassName Server ...
- IOS 基于TCP的socket通信详解(原创)
最近在整理通信层相关知识,这篇文章是边整理边写的,有些地方可能不够准确,还请各位路过的大牛专家指出来.这次整理的socket通信是基于TCP的,实现方式是GCD形式,以下记录的都是些理论知识,方便自己 ...
- 基于tcp的socket通信
# socket # socekt是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它 # 把复杂的tcp/ip协议族隐藏在socket接 ...
- python 之网络编程(基于TCP协议Socket通信的粘包问题及解决)
8.4 粘包问题 粘包问题发生的原因: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包),这样接收端,就难于分辨出来了,必须提供科学的拆包机制. ...
- 一个基于tcp的socket简单对话小例子
首先我们需要写连个py文件,一个server,一个client. import socket sk = socket.socket() # sk.bind(('ip',port)) sk.bind(( ...
- Java Web 基础(一) 基于TCP的Socket网络编程
一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...
- Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信
Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...
- 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...
- 事件驱动的TCP协议Socket通信
事件驱动的TCP协议Socket通信 介绍 常规的Socket通信案例一般都是在某个线程中建立连接,然后用一个while(true)循环判断是或否有数据传输,但是这种方法有局限性. 1.收到消息在处理 ...
随机推荐
- 【FJOI2014】【偏导+数学】病毒防护带
转载:http://trinklee.blog.163.com/blog/static/23815806020150155296528/ 问题描述: 众所周知,在国王胖哥的带领下,K国国泰民安,空前繁 ...
- 深入了解jquery中的键盘事件
很多时候,我们需要获取用户的键盘事件,下面就一起来看看jquery是如何操作键盘事件的. 一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() k ...
- linux下date命令实现时间戳与日期的转换
1.查看指定时间的时间戳 查看当前时间 #date +%s 查看指定时间 #date -d 2008-01-01 +%s 1199116800 #date -d 20080101 ...
- WPF2D绘制图形方法
我们先看看效果如何: xaml文件: <Window x:Class="WPF2D绘制图形方法.MainWindow" xmlns="http://schemas. ...
- 关于C# json转object时报错:XXXXXXXXXX需要标记“"”,但找到“XX”。
使用的类:System.Runtime.Serialization.Json.DataContractJsonSerializer //MessagePackage 为要转成的类DataContrac ...
- 通过CTAPI和Citect SCADA软件进行数据通讯
官方文档 Citect SCADA 7.20 Technical Reference 参考文献 基于Citect远程控制的变流量堆料控制系统 [王玉增,顾英妮,王维 济南大学,机械工程学院 ,Cite ...
- Web 研发模式演变
前不久徐飞写了一篇很好的文章:Web 应用的组件化开发.本文尝试从历史发展角度,说说各种研发模式的优劣. 一.简单明快的早期时代 可称之为 Web 1.0 时代,非常适合创业型小项目,不分前后端,经常 ...
- bzoj 1045: [HAOI2008] 糖果传递 贪心
1045: [HAOI2008] 糖果传递 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1812 Solved: 846[Submit][Stat ...
- 支付宝openssl漏洞肆虐 互联网巨头称目前已修复
支付宝openssl漏洞肆虐 互联网巨头称目前已修复 金山毒霸安全专家李铁军表示,这个漏洞使黑客可以远程读取https服务器的随机64KB内存,“只要这个黑客有耐心多捕获多分析那些64KB的数据,用户 ...
- PL/SQL 程序块
DECLARE BARCODE VARCHAR(50); BEGIN BARCODE := 'A'; IF BARCODE<>'A' then SELECT 1 FROM sam_user ...