网络编程(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)相关推荐

  1. linux常用c函数(中文版)

    都是linux的c函数东西略多,用页面搜索来查找吧. << Back to man.ChinaUnix.net isalnum(测试字符是否为英文或数字) 相关函数 isalpha,isd ...

  2. 百度前200页部分答案(初稿)

    1操作系统中 heap 和 stack 的区别 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. 在函数中定义的一些基本类 ...

  3. RPC 笔记(08)— socket 通信(多进程多线程服务器)

    在上一节中如果并行的客户端连接数超过了默认开启进程的数量,那么后来的客户端请求将会阻塞,为了不阻塞新的客户端,我们可以将进程的单线程改成多线程即可. ​ 服务端代码: import json impo ...

  4. RPC 笔记(07)— socket 通信(多进程服务器)

    上节我们完成了一个简单的多线程服务器,可以并发处理多个客户端连接.但是 Python 由于全局解释器锁 GIL 的存在,致使多个线程只能占满一个 CPU 核心,多线程并不能充分利用多核的优势.所以多数 ...

  5. RPC 笔记(06)— socket 通信(多线程服务器)

    1. 客户端代码 import json import time import struct import socketdef send_request(sock_obj, method, param ...

  6. RPC 笔记(05)— socket 通信(单线程服务器)

    1. Python 标准库 1.1 socket 提供 RPC 服务的网络通信功能,方便用户编写 tcp/udp 相关的代码.两个不同机器的进程需要通信时,可以通过 socket 来传输数据. ​ 客 ...

  7. 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. ...

  8. python 网络编程之Socket通信案例消息发送与接收

    背景 网络编程是python编程中的一项基本技术.本文将实现一个简单的Socket通信案例消息发送与接收 正文 在python中的socket编程的大致流程图如上所示 我们来首先编写客户端的代码: # ...

  9. 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 ...

  10. C# Socket系列三 socket通信的封包和拆包

    通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! 1 class Program 2 { 3 static void Mai ...

最新文章

  1. 关系抽取论文总结(relation extraction)不断更新
  2. c语言零基础快速入门,C语言几种循环结构—零基础小白快速入门必学
  3. python怎么输入代码-如何编写python代码
  4. vs2005的webbrowser控件如何接收鼠标事件
  5. mysql操作json优点和缺点_SQL-mysql操作json
  6. centos7:塔建pure_ftpd虚拟用户
  7. c语言如何打印unicode字符,如何在C ++中打印Unicode字符?
  8. NornJ-javascript模版引擎
  9. PEP 263 -- Defining Python Source Code Encodings(定义Python源代码编码)
  10. android电源管理白名单,刷BIOS工具分享(白名单,高级菜单,电源管理
  11. dcm文件如何转化为jpg或者bmp文件
  12. 知乎:1.03亿月活用户,获得感战略下的内容质量和商业化布局难平衡
  13. 好看wordpress图片主题
  14. 【数据库技术课程设计】 电信学院考研信息管理系统 +【Visual FoxPro】
  15. android bp文件_Android编译系统中的Android.bp【转】
  16. c++ 因数分解(递归)
  17. hexo下next主题的优化
  18. Git配置免密登录及常用操作的详细教程(基于Gitee平台)
  19. 算法面试题(格灵深瞳)
  20. 2019年中科大计算机夏令营经验帖

热门文章

  1. 递归,递推,记忆化搜索,空间优化(数字三角形)
  2. Dynamics CRM2013 Server2012R2下IFD部署遇到There is already a listener on IP endpoint的解决方法...
  3. linux之yum源设置代理
  4. JavaScript 获取当前时间戳的三种方式
  5. matlab3d绘图实例,matlab各种三维绘图及实例
  6. 再不了解PostgreSQL,你就晚了之PostgreSQL主从流复制部署...
  7. java常用序列化与反序列化方法
  8. mysqldump的一些用法
  9. 商业 - 业务领先模型介绍(BLM)
  10. 生成8位的不重复乱码