socket-(2)
网络编程(2)
网络编程需要使用通信地址 sockaddr_in,其中的端口和IP都要做转换,端口要从本机格式转网络格式,IP要从点分十进制转十六进制。函数:
htons() - 本机 转 网络
inet_addr() - 点分十进制 转 十六进制
ntohs() - 网络 转 本机(从网络取数据到本机)
inet_ntoa() - 十六进制 转 点分十进制
例子:简单的例子,就是将socket联通
例子1:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
int main(){
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1) perror("socket"),exit(-1);
struct sockaddr_in addr;
addr.sin_family = AF_INET;//网络
addr.sin_port = htons(2222);//端口需要处理一下
addr.sin_addr.s_addr = //IP需要转换
inet_addr("192.168.112.137");
int res = bind(sockfd,
(struct sockaddr*)&addr,sizeof(addr));
if(res == -1) perror("bind"),exit(-1);
printf("bind ok\n");
char buf[100] = {};
int len = read(sockfd,buf,sizeof(buf));
printf("读到了%d字节,内容:%s\n",len,buf);
close(sockfd);
}
例子2:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(){
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1) perror("socket"),exit(-1);
struct sockaddr_in addr;
addr.sin_family = AF_INET;//网络
addr.sin_port = htons(2222);//服务器的端口
addr.sin_addr.s_addr = //服务器的IP
inet_addr("192.168.112.135");
int res = connect(sockfd,
(struct sockaddr*)&addr,sizeof(addr));
if(res == -1) perror("connect"),exit(-1);
printf("connect ok\n");
write(sockfd,"hello",5);
close(sockfd);
}
aiyq195@aiyq195-virtual-machine:~/桌面/uc/day12/day12$ ./socknetabind ok
读到了5字节,内容:hello
aiyq195@aiyq195-virtual-machine:~/桌面/uc/day12/day12$ ./socknetb
connect ok
TCP网络编程
编程步骤:
一对多(也实现一对一):
服务器端:
1 创建socket描述符 socket()
2 准备通信地址,用sockaddr_in
3 绑定bind(),开放权限。
4 监听客户端的连接 listen()
5 等待客户端的连接 accept(),返回一个新的socket描述符,用于与客户端的交互。
6 read() write() 读写数据
7 close()
客户端的代码步骤不变。
listen(int sockfd,int backlog)
参数 sockfd 就是第一步的返回值
backlog就是当正在处理客户端连接时,有新的客户端连接,会把新的请求放入队列,backlog就是 这个队列的最大长度。而如果处理完毕,从队列中拿出新的请求,队列就会变短。
int accept(int sockfd,struct sockaddr* addr,socklen_t* len)
参数 sockfd 就是第一步的返回值
addr 用于存储 客户端的IP
len 是传入传出参数,传入addr的大小,传出真实的大小。
注:使用TCP编程时,socket()中的type必须用:SOCK_STREAM
accpet()函数会阻塞,直到有客户端连接才能解除。
信息交互时,服务器和客户端一定要保持读写的一致性。一个读,另外一个必须写。
例子:
例子1 tcpserver.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(){
int sockfd = socket(AF_INET,SOCK_STREAM,0);//1创建
if(sockfd == -1) perror("socket"),exit(-1);
struct sockaddr_in addr;//2 通信地址
addr.sin_family = AF_INET;
addr.sin_port = htons(2222);
addr.sin_addr.s_addr =
inet_addr("192.168.112.135");
int res = bind(sockfd, //3 绑定
(struct sockaddr*)&addr,sizeof(addr));
if(res == -1) perror("bind"),exit(-1);
printf("bind ok\n");
if(listen(sockfd,100) == -1) //4 监听
perror("listen"),exit(-1);
struct sockaddr_in from;//5 等待客户端连接
socklen_t len = sizeof(from);
int fd = accept(sockfd,(struct sockaddr*)&from,
&len);
if(fd == -1) perror("accpet"),exit(-1);
printf("客户端%s成功连接\n",
inet_ntoa(from.sin_addr));
char buf[100] = {};
read(fd,buf,sizeof(buf));
printf("buf=%s\n",buf);
write(fd,"welcome",7);
close(fd);
close(sockfd);
}
例子2: client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
int main(){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1) perror("socket"),exit(-1);
struct sockaddr_in addr;
addr.sin_family = AF_INET;//网络
addr.sin_port = htons(2222);//服务器的端口
addr.sin_addr.s_addr = //服务器的IP
inet_addr("192.168.112.135");
int res = connect(sockfd,
(struct sockaddr*)&addr,sizeof(addr));
if(res == -1) perror("connect"),exit(-1);
printf("connect ok\n");
char buf[100] = {};
while(1){
printf("请输入聊天的内容:\n");
scanf("%s",buf);//加‘\0’
//1 break;服务器不知道 客户端退出
write(sockfd,buf,strlen(buf));
if(!strcmp(buf,"bye")) break;
memset(buf,0,sizeof(buf));//清0
read(sockfd,buf,sizeof(buf));
printf("buf=%s\n",buf);
memset(buf,0,sizeof(buf));//清0
}
close(sockfd);
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <signal.h>
#include <string.h>
int sockfd;
void fa(int signo){
printf("关闭服务器\n");
close(sockfd);
exit(0);
}
int main(){
printf("按Ctrl+C退出服务器\n");
signal(SIGINT,fa);
sockfd = socket(AF_INET,SOCK_STREAM,0);//1创建
if(sockfd == -1) perror("socket"),exit(-1);
struct sockaddr_in addr;//2 通信地址
addr.sin_family = AF_INET;
addr.sin_port = htons(2222);
addr.sin_addr.s_addr =
inet_addr("192.168.112.135");
int reuseaddr = 1;//避免重启时 地址被占用 错误
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,
&reuseaddr,sizeof(reuseaddr));
int res = bind(sockfd, //3 绑定
(struct sockaddr*)&addr,sizeof(addr));
if(res == -1) perror("bind"),exit(-1);
printf("bind ok\n");
if(listen(sockfd,100) == -1) //4 监听
perror("listen"),exit(-1);
while(1){
struct sockaddr_in from;//5 等待客户端连接
socklen_t len = sizeof(from);
int fd = accept(sockfd,(struct sockaddr*)&from,
&len);
if(fd == -1) perror("accpet"),exit(-1);
printf("客户端%s成功连接\n",
inet_ntoa(from.sin_addr));
pid_t pid = fork();//accept()会阻塞
if(pid==0){
char buf[100] = {};
while(1){
int le = read(fd,buf,sizeof(buf));
if(le<=0) break;
printf("buf=%s\n",buf);
if(!strcmp(buf,"bye")) break;
write(fd,buf,le);
memset(buf,0,sizeof(buf));
}
close(fd); exit(0); }
close(fd);//父进程关闭描述符
}
//close(sockfd);//练习:用信号关闭sockfd。
}
转载于:https://www.cnblogs.com/aiyq195/p/6433419.html
socket-(2)相关推荐
- linux常用c函数(中文版)
都是linux的c函数东西略多,用页面搜索来查找吧. << Back to man.ChinaUnix.net isalnum(测试字符是否为英文或数字) 相关函数 isalpha,isd ...
- 百度前200页部分答案(初稿)
1操作系统中 heap 和 stack 的区别 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. 在函数中定义的一些基本类 ...
- RPC 笔记(08)— socket 通信(多进程多线程服务器)
在上一节中如果并行的客户端连接数超过了默认开启进程的数量,那么后来的客户端请求将会阻塞,为了不阻塞新的客户端,我们可以将进程的单线程改成多线程即可. 服务端代码: import json impo ...
- RPC 笔记(07)— socket 通信(多进程服务器)
上节我们完成了一个简单的多线程服务器,可以并发处理多个客户端连接.但是 Python 由于全局解释器锁 GIL 的存在,致使多个线程只能占满一个 CPU 核心,多线程并不能充分利用多核的优势.所以多数 ...
- RPC 笔记(06)— socket 通信(多线程服务器)
1. 客户端代码 import json import time import struct import socketdef send_request(sock_obj, method, param ...
- RPC 笔记(05)— socket 通信(单线程服务器)
1. Python 标准库 1.1 socket 提供 RPC 服务的网络通信功能,方便用户编写 tcp/udp 相关的代码.两个不同机器的进程需要通信时,可以通过 socket 来传输数据. 客 ...
- Docker使用遇到问题Got permission denied while trying to connect to the Docker daemon socket解决方案
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker. ...
- python 网络编程之Socket通信案例消息发送与接收
背景 网络编程是python编程中的一项基本技术.本文将实现一个简单的Socket通信案例消息发送与接收 正文 在python中的socket编程的大致流程图如上所示 我们来首先编写客户端的代码: # ...
- Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2)
安装了mysql, 使用命令mysql -u root -p 弹出Can 't connect to local MySQL server through socket '/tmp/mysql.soc ...
- C# Socket系列三 socket通信的封包和拆包
通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! 1 class Program 2 { 3 static void Mai ...
最新文章
- 关系抽取论文总结(relation extraction)不断更新
- c语言零基础快速入门,C语言几种循环结构—零基础小白快速入门必学
- python怎么输入代码-如何编写python代码
- vs2005的webbrowser控件如何接收鼠标事件
- mysql操作json优点和缺点_SQL-mysql操作json
- centos7:塔建pure_ftpd虚拟用户
- c语言如何打印unicode字符,如何在C ++中打印Unicode字符?
- NornJ-javascript模版引擎
- PEP 263 -- Defining Python Source Code Encodings(定义Python源代码编码)
- android电源管理白名单,刷BIOS工具分享(白名单,高级菜单,电源管理
- dcm文件如何转化为jpg或者bmp文件
- 知乎:1.03亿月活用户,获得感战略下的内容质量和商业化布局难平衡
- 好看wordpress图片主题
- 【数据库技术课程设计】 电信学院考研信息管理系统 +【Visual FoxPro】
- android bp文件_Android编译系统中的Android.bp【转】
- c++ 因数分解(递归)
- hexo下next主题的优化
- Git配置免密登录及常用操作的详细教程(基于Gitee平台)
- 算法面试题(格灵深瞳)
- 2019年中科大计算机夏令营经验帖
热门文章
- 递归,递推,记忆化搜索,空间优化(数字三角形)
- Dynamics CRM2013 Server2012R2下IFD部署遇到There is already a listener on IP endpoint的解决方法...
- linux之yum源设置代理
- JavaScript 获取当前时间戳的三种方式
- matlab3d绘图实例,matlab各种三维绘图及实例
- 再不了解PostgreSQL,你就晚了之PostgreSQL主从流复制部署...
- java常用序列化与反序列化方法
- mysqldump的一些用法
- 商业 - 业务领先模型介绍(BLM)
- 生成8位的不重复乱码