Socket基础编程
地址结构sockaddr_in
其中包含:IP地址,端口号,协议族
推荐使用sockaddr_in,而不建议使用sockaddrsockaddr_in与sockaddr是等价的,但sockaddr_in字段更清晰
/*
* Socket address, internet style.
*/
struct sockaddr_in {
__uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
];
};
sockaddr_in字段描述
// 地址家族,通常使用AF_INET代表TCP/CP协议族(AF_INET6代表IPV6) sockaddr_in.sin_family // 端口号,必须转化为网络字节序使用htons和ntohs sockaddr_in.sin_port // 用于存储ip地址,必须是网络字节序 sockaddr_in.sin_addr // 为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节 sockaddr_in.sin_zero
sockaddr_in字段初始化
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
// 若字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 检测转化IP是否出错
if (servaddr.sin_addr.s_addr == INADDR_NONE) {
perror("ip");
exit(-);
}
可以支持IPV6的IP地址转换方式
// inet_pton能够处理ipv4甚至ipv6(需要改动现在代码)
) {
perror("pton");
exit(-);
}
网络字节序和IP转换函数
// 将网络字节序转化为主机字节序 __uint16_t ntohs(__uint16_t); // 将主机字节序转化为网络字节序 __uint16_t htons(__uint16_t); __uint32_t ntohl(__uint32_t); __uint32_t htonl(__uint32_t); // 若字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址,否则为INADDR_NONE // 其反函数inet_ntoa in_addr_t inet_addr(const char* strptr);
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释,网络字节顺序采用big-endian排序方式。
|
序号
|
英文名
|
中文名
|
描述
|
|
1
|
big-endian
|
大尾顺序
|
地址的低位存储值的高位
|
|
2
|
little-endian
|
小尾顺序
|
地址的低位存储值的低位
|
想判断你的设备大小端吗?使用C语言的Union就可以判断!请看这里
套接字
创建一个套接字,返回一个套接字描述符
int socket(int domain, int type, int protocol);
套接字描述符(socket file descriptor)
套接字描述符是一个整数类型的值,每个进程的进程空间里都有一个套接字描述符表,表中存放着套接字描述符和套接字数据结构的对应关系。
因此根据套接字描述符就可以找到其对应的套接字数据结构。
每个进程在自己的进程空间里都有一个套接字描述符表,但是套接字数据结构都是在操作系统的内核缓冲里
接收发送函数
ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); ssize_t send(int sockfd, const void *buff, size_t nbytes, int flags); ssize_t write (int fd,const void * buf,size_t count); ssize_t read(int fd,void * buf ,size_t count);
客户端主要函数
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
服务器端主要函数
int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen); int listen(int s, int backlog); int accept(int s, struct sockaddr * addr, int * addrlen);
客户端代码
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
;
;
const char* SERV_IP = "127.0.0.1";
int main(int argc, const char * argv[])
{
int socketfd;
struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
// 若字符串有效则将字符串转换为32位二进制网络字节序的IPV4地址
// servaddr.sin_addr.s_addr = inet_addr(SERV_IP);
// if (servaddr.sin_addr.s_addr == INADDR_NONE) {
// perror("ip");
// exit(-1);
// }
// 支持IPV6的新的转换方式,推荐
) {
perror("pton");
exit(-);
}
// 创建一个套接字
)) < ) {
perror("socket");
exit(-);
}
// 连接到主机
) {
perror("connect");
exit(-);
}
// 接收数据
];
;
) {
recvline[bytelen] = ;
printf("recv --> %s\n", recvline);
}
close(socketfd);
;
}
服务器代码
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>
;
int main(int argc, const char * argv[])
{
struct sockaddr_in serveraddr;
memset(&serveraddr, , sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
// 系统自动获取本机IP
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 创建一个socket
);
) {
perror("socket");
exit(-);
}
// 绑定端口
int bind_ret = bind(serverfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
) {
perror("bind");
exit(-);
}
// 开始监听
// #2: backlog:等待连接队列的最大长度
) < ) {
perror("listen");
exit(-);
}
printf("---------- listening (127.0.0.1:%d) ----------\n", SERV_PORT);
// 开始轮询监听请求
bool toggle = true;
while (toggle) {
// 客户端信息结构
int clientfd;
struct sockaddr_in clientaddr;
memset(&serveraddr, , sizeof(serveraddr));
socklen_t len = sizeof(clientaddr);
// 接收请求,建立连接
) {
perror("accept");
exit(-);
}
// 向客户端发送信息
const char *message = "hello world";
write(clientfd, message, strlen(message)+);
// 转为点分十进制ip
const char *client_ip = inet_ntoa(clientaddr.sin_addr);
const ushort client_port = ntohs(clientaddr.sin_port);
printf("client(%s:%u) # send -> %s\n", client_ip, client_port, message);
// 关闭与客户端的连接
close(clientfd);
}
// 关闭服务监听
close(serverfd);
;
}
Socket基础编程的更多相关文章
- 【Socket】Java Socket基础编程
Socket是Java网络编程的基础,了解还是有好处的, 这篇文章主要讲解Socket的基础编程.Socket用在哪呢,主要用在进程间,网络间通信.本篇比较长,特别做了个目录: 一.Socket通信基 ...
- C#网络程序设计(2)Socket基础编程
本节介绍如何使用基础Socket实现TCP通信. (1)Socket详细介绍: Socket的英文原义是"孔"或"插座".通常称作"套 ...
- TCP(Socket基础编程)
1.TCP特点: 面向连接.可靠安全.传输量大.速度较慢 2.socket编程主要依靠两个类:socket .serversocket example1:客户端可以不停输入字符串,服务端返回字符串的大 ...
- socket基础编程-1
server端和client端 1.server端: import socket server=socket.socket() server.bind(('localhost',8080)) serv ...
- socket基础编程-2
client端: import socket while True: client=socket.socket(socket.ANET,socket.SOCK_STREAM) client.conne ...
- C++ SOCKET 基础编程
{ http://c.biancheng.net/socket/ }
- Linux应用程序设计之网络基础编程
1.TCP/IP协议概述 1.1.OSI参考模型及TCP/IP参考模型 OSI协议参考模型是基于国际标准化组织(ISO)的建议发展起来的,从上到下工分为7层:应用层,表示层,会话层,传输层,网络层,数 ...
- Python基础笔记系列十三:socket网络编程
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!!使用python编写一个简易的服务端程序和客户端程序,启动服务端和客户端(监 ...
- Java Web 基础(一) 基于TCP的Socket网络编程
一.Socket简单介绍 Socket通信作为Java网络通讯的基础内容,集中了异常.I/O流模式等众多知识点.学习Socket通信,既能够了解真正的网络通讯原理,也能够增强对I/O流模式的理解. 1 ...
随机推荐
- Python中的高阶函数与匿名函数
Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...
- android 开发 system/app目录下面有多个重复包名的apk,会不会冲突
环境:已经拥有了root权限的android系统,我们的apk是开机启动 测试:将2个相同的版本拷贝到系统system/app目录下面 adb root #获取root权限,前提是已经开放了root权 ...
- 链路层三种类型的MAC地址
若需要转载,请注明出处. 我们知道,链路层都是以MAC地址来进行通信双方的地址标识的,如下图:在应用中根据接收方的多寡来进行划分,可分为以下三种: 单播(Unicast) 多播(Multicast) ...
- 使用CSS时间打点的Loading效果的教程
基于box-shadow实现的打点效果 理论上,box-shadow可以实现任意的图形效果,自然我们可以利用box-shadow生成我们的点效果,然后通过animation控制不同时间点点的数目就可以 ...
- BZOJ2457 BeiJing2011 双端队列
[问题描述] Sherry现在碰到了一个棘手的问题,有N个整数需要排序. Sherry手头能用的工具就是若干个双端队列. 她需要依次处理这N个数,对于每个数,Sherry能做以下两件事 ...
- [百度空间] [原] Empty base class optimization
最近遇到了一个诡异的问题, 数组的数据不对, 最后发现是两个类型的大小不一样导致的. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
- nodejs快速入门
目录: 编写第一个Node.js程序: 异步式I/O和事件循环: 模块和包: 调试. 1. 编写第一个Node.js程序: Node.js 具有深厚的开源血统,它诞生于托管了许多优秀开源项目的网站—— ...
- IE6 IE7 IE8(Q) 不支持 JSON 对象
标准参考 JSON 是一种数据交换格式,RFC 4627 对 JSON 进行了详细描述. 根据 ECMA-262(ECMAScript)第 5 版中描述,JSON 是一个包含了函数 parse 和 s ...
- javascript实现数据结构与算法系列:循环链表与双向链表
循环链表(circular linked list) 是另一种形式的链式存储结构.它的特点是表中最后一个结点的指针域指向头结点,整个表形成一个环. 循环链表的操作和线性链表基本一致,仅有细微差别. w ...
- linux使用crontab实现PHP执行定时任务及codeiginter参数传递相关
http://www.phpddt.com/php/linux-crontab.html crontab: yum install crontabs //安装 说明: /sbin/service cr ...