`
bcyy
  • 浏览: 1823909 次
文章分类
社区版块
存档分类
最新评论

socket创建流程及代码示例

 
阅读更多
socket操作
1.1 创建socket
int socket(int domain, int type, int protocol);
domain: 确定通信的特性
AF_INET IPv4因特网域
AF_INET6 IPv6因特网域
AF_UNIX UNIX域
AF_UNSPEC 未指定
type: 指定套接字的类型
SOCK_DGRAM 长度固定的、无连接的不可靠报文传递
SOCK_RAW IP协议的数据报接口(POSIX.1中可选)
SOCK_SEQPACKET 长度固定、有序、可靠的面向连接报文传递
SOCK_STREAM 有序、可靠、双向的面向连接字节流
protocol参数通常是0,表示按给定的域和套接字类型选择默认协议。当同一域和套接字类型支持多个协议的时候,可以使用protocol参数选择一个特定的协议。
AF_INET通信域中套接字类型SOCK_STREAM的默认协议是TCP(传输控制协议)
AF_INET通信与中套接字类型SOCK_DGRAM的默认协议是UDP(用户数据报协议)
1.2 绑定地址(server)
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
sockfd: 要绑定的套接字
my_addr: 地址结构体
addrlen: 结构体长度,通常为sizeof(my_addr)
1.2.1 struct sockaddr
该结构体定义了地址信息
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
1.2.2 网络字节转换
网络中的数据格式为大端,所以需要将小端存储的数据转换成为大端存储,一下为网络字节序和本地字节序(小端)之间转换函数
uint32_t htonl(uint32_t hostint32); /// host to net long(uint32_t)
uint16_t htons(uint16_t hostint16); /// host to net short(uint16_t)
uint32_t ntohl(uint32_t netint32); /// net to host long(uint32_t)
uint16_t ntohs(uint16_t netint16); /// net to host short(uint16_t)
1.2.3inet_pton
int inet_pton(int af, const char *src, void *dst);
将字符串类型的地址转换成为struct sockaddr_in::sin_addr类型
af: 通信特性
src: 地址字符串
dst:truct sockaddr_in::sin_addr类型,长度必需为sizeof(struct in_addr).
1.2.4 查询地址
#include <netdb.h>
struct hostent *gethostent(void); ///(打开主机数据文件)返回struct hostent
void endhostent(void); /// 关闭打开的主机数据文件
void sethostent(int stayopen); ///打开主机数据文件
struct hostent {
char *h_name; /// 主机名
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
. . .
};
设置地址的例子:
struct sockaddr_in laddr;
laddr.sin_family = AF_INET;
laddr.sin_port = hotns(atoi(SERVERPORT));
inet_pton(AF_INET, "0.0.0.0", &laddr.sin_addr);
1.3 建立连接(client)
int connect(int sockfd, const struct sockaddr* my_addr, socket_t addrlen);
sockfd: 套接字
my_addr: 想连接的服务器的地址
addrlen: 地址结构的长度,通常为sizeof(my_addr)
1.4 服务器宣告可以接受连接请求 listen
int listen(int sockfd, int backlog);
backlog: 该进程最大的入队连接请求数
1.5 获得连接请求并建立连接 accept
int accept(int sockfd,struct sockaddr*my_addr, socket_t*addrlen);
my_addr: 用户地址
addrlen: 用户地址长度
1.6 发数据(client)
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
sockfd: 套接字
buf: 要发送数据的buf
nbytes: buf长度
flags: 发送标识
MSG_DONTROUTE: 勿将数据路由出本地网络
MSG_DONTWAIT: 允许非阻塞操作
MSG_EOR: 如果协议支持,此为记录结束
MSG_OOB: 如果协议支持,发送外带数据

1.7 收数据(server)
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
sockfd: 套接字
buf: 接收数据的buf
nbytes: buf长度
flags: 发送标识
MSG_OOB: 如果协议支持,接收外带数据
MSG_PRRK: 返回报文内容而不真正取走报文
MSG_TRUNC: 即使报文被截断,要求返回的是报文的实际长度
MSG_WAITALL: 等待直到所有的数据可用(仅SOCK_STREAM)

mysocket.h

#ifndef MYSOCKET_H_INCLUDED
#define MYSOCKET_H_INCLUDED

#include <iostream>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>

#define SERVERPORT "1234"
#define SERVERIP "127.0.0.1"
#define MAXBACKLOG 10
#define MAXIPSIZE 20
#define BUFMAXSIZE 1024*1024
#define WRITEFILEPATH "./recvFile"
#define READFILEPATH "./a.tgz"

using namespace std;

#endif // MYSOCKET_H_INCLUDED


client.cpp

#include "mysocket.h"

int main()
{
int iRet = 0;
int sockFd = 0;
struct sockaddr_in serverAddr;
sockFd = socket(AF_INET, SOCK_STREAM, 0);
char sendBuf[BUFMAXSIZE];
if (sockFd < 0) {
cout << "socket is error" << endl;
} else {
cout << "socket is ok" << endl;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(atoi(SERVERPORT));
inet_pton(AF_INET, SERVERIP, &serverAddr.sin_addr);
iRet = connect(sockFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (iRet < 0) {
cout << "connect is error." << endl;
} else {
cout << "connect is ok." << endl;
}
FILE *rfp = fopen(READFILEPATH, "rb+");
while(1) {
iRet = fread(sendBuf, 1, BUFMAXSIZE, rfp);
cout << "fork:fread ret = " << iRet << endl;
if (iRet < 0) {
cout << "fread is error" << endl;
break;
}
iRet = send(sockFd, sendBuf, iRet, 0);
if (iRet < BUFMAXSIZE) {
cout << "fread is eof" << endl;
break;
}
}
fclose(rfp);
return 0;
}

server.cpp

#include "mysocket.h"

int main()
{
int iRet = 0;
int sockFd = 0;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientLen = 0;
char clientIP[MAXIPSIZE];
char recvBuf[BUFMAXSIZE];
sprintf(recvBuf, "rm %s", WRITEFILEPATH);
system(recvBuf);
memset(recvBuf, 0, BUFMAXSIZE);
int recvLen = 0;
FILE *fp = NULL, *wfp = NULL;
sockFd = socket(AF_INET, SOCK_STREAM, 0); /// create socket
if (sockFd < 0) {
cout << "socket is error" << endl;
} else {
cout << "socket is ok" << endl;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(atoi(SERVERPORT));
inet_pton(AF_INET, "0.0.0.0", &serverAddr.sin_addr);
iRet = bind(sockFd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)); /// bind addr
if (iRet < 0) {
cout << "bind is error." << endl;
} else {
cout << "bind is ok." << endl;
}

iRet = listen(sockFd, MAXBACKLOG); /// listen
if (iRet < 0) {
cout << "listen is error." << endl;
} else {
cout << "listen is ok." << endl;
}
int newSd;
while(1) {
newSd = accept(sockFd, (struct sockaddr*)&clientAddr, &clientLen);
if (newSd < 0) {
cout << "accept is error : iRet = " << iRet << endl;
break;
}
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, MAXIPSIZE);
cout << "client: " << clientIP << " : " << ntohs(clientAddr.sin_port) << " is connected" << endl;

if (fork() == 0) {
wfp = fopen(WRITEFILEPATH, "ab+");
fp = fdopen ( newSd, "r+" );
while (1) {
iRet = fread ( recvBuf, 1, BUFMAXSIZE, fp );
if (iRet <= 0) {
cout << "recv is done" << endl;
break;
}
fwrite(recvBuf, 1, iRet, wfp);
}
fclose(fp);
fclose(wfp);
}
sleep(1);
}

return 0;
}




阅读(230) | 评论(0) | 转发(2) |
评论热议
分享到:
评论

相关推荐

    《Delphi 深度编程及其项目应用开发》PDF书及代码

    基础篇结合示例论述了Delphi的深度编程技术,其中包括9章,分别为:理解Windows消息、进程与线程、自定义组件的编写、文件操作、创建DLL应用程序、两层数据库应用程序、多层数据库应用程序、Socket编程、串口编程;...

    JAVA上百实例源码以及开源项目源代码

    Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个...

    Python udp网络程序实现发送、接收数据功能示例

    创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8 from socket import * # 1. 创建udp套接字 udp_socket = socket(AF_INET, SOCK_...

    JAVA上百实例源码以及开源项目源代码 java开源包2

    EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean...

    Delphi深度编程技术

    9.3 利用API函数创建串口通信示例 9.3.1 发送数据部分设计(向串口写数据) 9.3.2 数据部分设计(从串口读数据) 9.3.3 程序的具体设计和实现 9.4 利用SPC0MM组件实现串口通信编程 9.4.1 SPCOMM组件的安装 9.4.2 ...

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    创建多对多以及增加示例 本节内容梳理 本周作业 第21周 今日知识点概要 上节内容回顾以及URL的补充 视图获取用户请求相关信息以及请求头 模板之继承 模板之导入 上节作业情况 自定义 simple_tag 自定义filter ...

    PHP 进程池与轮询调度算法实现多任务的示例代码

    phper 请了解进程调度策略,CPU 时间片,进程控制【创建,销毁,回收,进程信号】与及进程运行流程和基本的进程组,信号中断原理,以及进程之间的关系。 关于进程的更多内容可参考本人前面撸过的文章或是百度了解。...

    机智云公版开源App-智能插座Android版

    这是一款使用XPGWifiSDK的开源代码示例APP,可以帮助开发者快速入手,使用XPGWifiSDK开发连接机智云的物联APP。该APP针对的是智能家电中的插座类产品。包括了以下几点插座常用功能: ▪ 插座电源的开关 ▪ 插座定时...

    Chatrooms-using-react_socket.io_express

    该存储库是一个聊天室的示例,该聊天室是使用具有Node.js(Express)后端和React前端的socket.io创建的。遵循逻辑流程图和组件文件的注释,以了解所有代码背后的工作。 在这里测试: :

    java源码包---java 源码 大量 实例

    EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean...

    精通并发与netty视频教程(2018)视频教程

    31_gRPC在Nodejs领域中的静态代码生成及与Java之间的RPC通信 32_IO体系架构系统回顾与装饰模式的具体应用 33_Java NIO深入详解与体系分析 34_Buffer中各重要状态属性的含义与关系图解 35_Java NIO核心类源码解读与...

    精通并发与 netty 视频教程(2018)视频教程

    20_通过Apache Thrift实现Java与Python的RPC调用 21_gRPC深入详解 22_gRPC实践 23_Gradle Wrapper在Gradle项目构建中的最佳实践 24_gRPC整合Gradle与代码生成 25_gRPC通信示例与JVM回调钩子 26_gRPC服务器流式调用...

    Java范例开发大全 (源程序)

     实例32 优良及差 47  实例33 打印任意一年日历 48  实例34 一年四季的划分 51  第2篇 Java数据处理  第4章 异常处理(教学视频:62分钟) 54  4.1 编译时异常 54  实例35 除0发生的算术异常...

    java源码包2

    EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证...

    Java开发技术大全 电子版

    2.5流程控制语句58 2.5.1三种基本控制结构58 2.5.2表达式语句和空语句59 2.5.3块语句60 2.5.4if~else分支语句61 2.5.5多路分支switch~case语句69 2.5.6当型循环while语句71 2.5.7直到型循环do~while语句72...

    javaSE代码实例

    10.4.1 构造器的调用流程及默认构造器 182 10.4.2 自定义构造器需要注意的问题 185 10.4.3 不能继承构造器 186 10.4.4 调用兄弟构造器 187 10.5 单列模式 189 10.6 Java程序的加载过程 190 10.7 小结 ...

    Visual C++2010开发权威指南(共三部分).part1.rar

    2.2.2 MFC应用程序运行流程 50 2.2.3 应用程序窗口 51 2.2.4 消息机制与消息循环 59 2.3 文档与视图 65 2.3.1 文档类结构分析 65 2.3.2 视图类结构分析 65 2.3.3 文档与视图的关系 67 2.3.4 sdi应用程序分析 69 ...

Global site tag (gtag.js) - Google Analytics