⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000004.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/types.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;socket(int&nbsp;domain,&nbsp;int&nbsp;type,&nbsp;int&nbsp;protocol);&nbsp;<BR>But&nbsp;what&nbsp;are&nbsp;these&nbsp;arguments?&nbsp;First,&nbsp;domain&nbsp;should&nbsp;be&nbsp;set&nbsp;to&nbsp;&quot;AF_INET&quot;,&nbsp;just&nbsp;<BR>&nbsp;<BR>like&nbsp;in&nbsp;the&nbsp;struct&nbsp;sockaddr_in&nbsp;(above.)&nbsp;Next,&nbsp;the&nbsp;type&nbsp;argument&nbsp;tells&nbsp;the&nbsp;<BR>kernel&nbsp;what&nbsp;kind&nbsp;of&nbsp;socket&nbsp;this&nbsp;is:&nbsp;SOCK_STREAM&nbsp;or&nbsp;SOCK_DGRAM.&nbsp;Finally,&nbsp;just&nbsp;<BR>&nbsp;<BR>set&nbsp;protocol&nbsp;to&nbsp;&quot;0&quot;.&nbsp;(Notes:&nbsp;there&nbsp;are&nbsp;many&nbsp;more&nbsp;domains&nbsp;than&nbsp;I've&nbsp;listed.&nbsp;<BR>There&nbsp;are&nbsp;many&nbsp;more&nbsp;types&nbsp;than&nbsp;I've&nbsp;listed.&nbsp;See&nbsp;the&nbsp;socket()&nbsp;man&nbsp;page.&nbsp;Also,&nbsp;<BR>&nbsp;<BR>there's&nbsp;a&nbsp;&quot;better&quot;&nbsp;way&nbsp;to&nbsp;get&nbsp;the&nbsp;protocol.&nbsp;See&nbsp;the&nbsp;getprotobyname()&nbsp;man&nbsp;<BR>page.)&nbsp;<BR>socket()&nbsp;simply&nbsp;returns&nbsp;to&nbsp;you&nbsp;a&nbsp;socket&nbsp;descriptor&nbsp;that&nbsp;you&nbsp;can&nbsp;use&nbsp;in&nbsp;later&nbsp;<BR>&nbsp;<BR>system&nbsp;calls,&nbsp;or&nbsp;-1&nbsp;on&nbsp;error.&nbsp;The&nbsp;global&nbsp;variable&nbsp;errno&nbsp;is&nbsp;set&nbsp;to&nbsp;the&nbsp;<BR>error's&nbsp;value&nbsp;(see&nbsp;the&nbsp;perror()&nbsp;man&nbsp;page.)&nbsp;<BR>----------------------------------------------------------------------------&nbsp;<BR>&nbsp;<BR>8.&nbsp;bind()--What&nbsp;port&nbsp;am&nbsp;I&nbsp;on?&nbsp;<BR>Once&nbsp;you&nbsp;have&nbsp;a&nbsp;socket,&nbsp;you&nbsp;might&nbsp;have&nbsp;to&nbsp;associate&nbsp;that&nbsp;socket&nbsp;with&nbsp;a&nbsp;port&nbsp;<BR>on&nbsp;your&nbsp;local&nbsp;machine.&nbsp;(This&nbsp;is&nbsp;commonly&nbsp;done&nbsp;if&nbsp;you're&nbsp;going&nbsp;to&nbsp;listen()&nbsp;<BR>for&nbsp;incoming&nbsp;connections&nbsp;on&nbsp;a&nbsp;specific&nbsp;port--MUDs&nbsp;do&nbsp;this&nbsp;when&nbsp;they&nbsp;tell&nbsp;you&nbsp;<BR>&nbsp;<BR>to&nbsp;&quot;telnet&nbsp;to&nbsp;x.y.z&nbsp;port&nbsp;6969&quot;.)&nbsp;If&nbsp;you're&nbsp;going&nbsp;to&nbsp;only&nbsp;be&nbsp;doing&nbsp;a&nbsp;<BR>connect(),&nbsp;this&nbsp;may&nbsp;be&nbsp;unnecessary.&nbsp;Read&nbsp;it&nbsp;anyway,&nbsp;just&nbsp;for&nbsp;kicks.&nbsp;<BR>Here&nbsp;is&nbsp;the&nbsp;synopsis&nbsp;for&nbsp;the&nbsp;bind()&nbsp;system&nbsp;call:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/types.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;bind(int&nbsp;sockfd,&nbsp;struct&nbsp;sockaddr&nbsp;*my_addr,&nbsp;int&nbsp;addrlen);&nbsp;<BR>sockfd&nbsp;is&nbsp;the&nbsp;socket&nbsp;file&nbsp;descriptor&nbsp;returned&nbsp;by&nbsp;socket().&nbsp;my_addr&nbsp;is&nbsp;a&nbsp;<BR>pointer&nbsp;to&nbsp;a&nbsp;struct&nbsp;sockaddr&nbsp;that&nbsp;contains&nbsp;information&nbsp;about&nbsp;your&nbsp;address,&nbsp;<BR>namely,&nbsp;port&nbsp;and&nbsp;IP&nbsp;address.&nbsp;addrlen&nbsp;can&nbsp;be&nbsp;set&nbsp;to&nbsp;sizeof(struct&nbsp;sockaddr).&nbsp;<BR>Whew.&nbsp;That's&nbsp;a&nbsp;bit&nbsp;to&nbsp;absorb&nbsp;in&nbsp;one&nbsp;chunk.&nbsp;Let's&nbsp;have&nbsp;an&nbsp;example:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;string.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/types.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;MYPORT&nbsp;3490&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;main()&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;sockfd;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;sockaddr_in&nbsp;my_addr;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sockfd&nbsp;=&nbsp;socket(AF_INET,&nbsp;SOCK_STREAM,&nbsp;0);&nbsp;/*&nbsp;do&nbsp;some&nbsp;error&nbsp;checking!&nbsp;<BR>&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_family&nbsp;=&nbsp;AF_INET;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;host&nbsp;byte&nbsp;order&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_port&nbsp;=&nbsp;htons(MYPORT);&nbsp;/*&nbsp;short,&nbsp;network&nbsp;byte&nbsp;order&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_addr.s_addr&nbsp;=&nbsp;inet_addr(&quot;132.241.5.10&quot;);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bzero(&amp;(my_addr.sin_zero),&nbsp;8);&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;zero&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;struct&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;don't&nbsp;forget&nbsp;your&nbsp;error&nbsp;checking&nbsp;for&nbsp;bind():&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bind(sockfd,&nbsp;(struct&nbsp;sockaddr&nbsp;*)&amp;my_addr,&nbsp;sizeof(struct&nbsp;sockaddr));&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;<BR>There&nbsp;are&nbsp;a&nbsp;few&nbsp;things&nbsp;to&nbsp;notice&nbsp;here.&nbsp;my_addr.sin_port&nbsp;is&nbsp;in&nbsp;Network&nbsp;Byte&nbsp;<BR>Order.&nbsp;So&nbsp;is&nbsp;my_addr.sin_addr.s_addr.&nbsp;Another&nbsp;thing&nbsp;to&nbsp;watch&nbsp;out&nbsp;for&nbsp;is&nbsp;that&nbsp;<BR>&nbsp;<BR>the&nbsp;header&nbsp;files&nbsp;might&nbsp;differ&nbsp;from&nbsp;system&nbsp;to&nbsp;system.&nbsp;To&nbsp;be&nbsp;sure,&nbsp;you&nbsp;should&nbsp;<BR>check&nbsp;your&nbsp;local&nbsp;man&nbsp;pages.&nbsp;<BR>Lastly,&nbsp;on&nbsp;the&nbsp;topic&nbsp;of&nbsp;bind(),&nbsp;I&nbsp;should&nbsp;mention&nbsp;that&nbsp;some&nbsp;of&nbsp;the&nbsp;process&nbsp;of&nbsp;<BR>&nbsp;<BR>getting&nbsp;your&nbsp;own&nbsp;IP&nbsp;address&nbsp;and/or&nbsp;port&nbsp;can&nbsp;can&nbsp;be&nbsp;automated:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_port&nbsp;=&nbsp;0;&nbsp;/*&nbsp;choose&nbsp;an&nbsp;unused&nbsp;port&nbsp;at&nbsp;random&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_addr.s_addr&nbsp;=&nbsp;INADDR_ANY;&nbsp;&nbsp;/*&nbsp;use&nbsp;my&nbsp;IP&nbsp;address&nbsp;*/&nbsp;<BR>See,&nbsp;by&nbsp;setting&nbsp;my_addr.sin_port&nbsp;to&nbsp;zero,&nbsp;you&nbsp;are&nbsp;telling&nbsp;bind()&nbsp;to&nbsp;choose&nbsp;<BR>the&nbsp;port&nbsp;for&nbsp;you.&nbsp;Likewise,&nbsp;by&nbsp;setting&nbsp;my_addr.sin_addr.s_addr&nbsp;to&nbsp;<BR>INADDR_ANY,&nbsp;you&nbsp;are&nbsp;telling&nbsp;it&nbsp;to&nbsp;automatically&nbsp;fill&nbsp;in&nbsp;the&nbsp;IP&nbsp;address&nbsp;of&nbsp;<BR>the&nbsp;machine&nbsp;the&nbsp;process&nbsp;is&nbsp;running&nbsp;on.&nbsp;<BR>If&nbsp;you&nbsp;are&nbsp;into&nbsp;noticing&nbsp;little&nbsp;things,&nbsp;you&nbsp;might&nbsp;have&nbsp;seen&nbsp;that&nbsp;I&nbsp;didn't&nbsp;<BR>put&nbsp;INADDR_ANY&nbsp;into&nbsp;Network&nbsp;Byte&nbsp;Order!&nbsp;Naughty&nbsp;me.&nbsp;However,&nbsp;I&nbsp;have&nbsp;inside&nbsp;<BR>info:&nbsp;INADDR_ANY&nbsp;is&nbsp;really&nbsp;zero!&nbsp;Zero&nbsp;still&nbsp;has&nbsp;zero&nbsp;on&nbsp;bits&nbsp;even&nbsp;if&nbsp;you&nbsp;<BR>rearrange&nbsp;the&nbsp;bytes.&nbsp;However,&nbsp;purists&nbsp;will&nbsp;point&nbsp;out&nbsp;that&nbsp;there&nbsp;could&nbsp;be&nbsp;a&nbsp;<BR>parallel&nbsp;dimension&nbsp;where&nbsp;INADDR_ANY&nbsp;is,&nbsp;say,&nbsp;12&nbsp;and&nbsp;that&nbsp;my&nbsp;code&nbsp;won't&nbsp;work&nbsp;<BR>there.&nbsp;That's&nbsp;ok&nbsp;with&nbsp;me:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_port&nbsp;=&nbsp;htons(0);&nbsp;/*&nbsp;choose&nbsp;an&nbsp;unused&nbsp;port&nbsp;at&nbsp;random&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_addr.sin_addr.s_addr&nbsp;=&nbsp;htonl(INADDR_ANY);&nbsp;&nbsp;/*&nbsp;use&nbsp;my&nbsp;IP&nbsp;address&nbsp;*&nbsp;<BR>/&nbsp;<BR>Now&nbsp;we're&nbsp;so&nbsp;portable&nbsp;you&nbsp;probably&nbsp;wouldn't&nbsp;believe&nbsp;it.&nbsp;I&nbsp;just&nbsp;wanted&nbsp;to&nbsp;<BR>point&nbsp;that&nbsp;out,&nbsp;since&nbsp;most&nbsp;of&nbsp;the&nbsp;code&nbsp;you&nbsp;come&nbsp;across&nbsp;won't&nbsp;bother&nbsp;running&nbsp;<BR>INADDR_ANY&nbsp;through&nbsp;htonl().&nbsp;<BR>bind()&nbsp;also&nbsp;returns&nbsp;-1&nbsp;on&nbsp;error&nbsp;and&nbsp;sets&nbsp;errno&nbsp;to&nbsp;the&nbsp;error's&nbsp;value.&nbsp;<BR>Another&nbsp;thing&nbsp;to&nbsp;watch&nbsp;out&nbsp;for&nbsp;when&nbsp;calling&nbsp;bind():&nbsp;don't&nbsp;go&nbsp;underboard&nbsp;with&nbsp;<BR>&nbsp;<BR>your&nbsp;port&nbsp;numbers.&nbsp;All&nbsp;ports&nbsp;below&nbsp;1024&nbsp;are&nbsp;RESERVED!&nbsp;You&nbsp;can&nbsp;have&nbsp;any&nbsp;port&nbsp;<BR>number&nbsp;above&nbsp;that,&nbsp;right&nbsp;up&nbsp;to&nbsp;65535&nbsp;(provided&nbsp;they&nbsp;aren't&nbsp;already&nbsp;being&nbsp;<BR>used&nbsp;by&nbsp;another&nbsp;program.)&nbsp;<BR>One&nbsp;small&nbsp;extra&nbsp;final&nbsp;note&nbsp;about&nbsp;bind():&nbsp;there&nbsp;are&nbsp;times&nbsp;when&nbsp;you&nbsp;won't&nbsp;<BR>absolutely&nbsp;have&nbsp;to&nbsp;call&nbsp;it.&nbsp;If&nbsp;you&nbsp;are&nbsp;connect()'ing&nbsp;to&nbsp;a&nbsp;remote&nbsp;machine&nbsp;and&nbsp;<BR>&nbsp;<BR>you&nbsp;don't&nbsp;care&nbsp;what&nbsp;your&nbsp;local&nbsp;port&nbsp;is&nbsp;(as&nbsp;is&nbsp;the&nbsp;case&nbsp;with&nbsp;telnet),&nbsp;you&nbsp;can&nbsp;<BR>&nbsp;<BR>simply&nbsp;call&nbsp;connect(),&nbsp;it'll&nbsp;check&nbsp;to&nbsp;see&nbsp;if&nbsp;the&nbsp;socket&nbsp;is&nbsp;unbound,&nbsp;and&nbsp;will&nbsp;<BR>&nbsp;<BR>bind()&nbsp;it&nbsp;to&nbsp;an&nbsp;unused&nbsp;local&nbsp;port.&nbsp;<BR>----------------------------------------------------------------------------&nbsp;<BR>&nbsp;<BR>9.&nbsp;connect()--Hey,&nbsp;you!&nbsp;<BR>Let's&nbsp;just&nbsp;pretend&nbsp;for&nbsp;a&nbsp;few&nbsp;minutes&nbsp;that&nbsp;you're&nbsp;a&nbsp;telnet&nbsp;application.&nbsp;Your&nbsp;<BR>user&nbsp;commands&nbsp;you&nbsp;(just&nbsp;like&nbsp;in&nbsp;the&nbsp;movie&nbsp;TRON)&nbsp;to&nbsp;get&nbsp;a&nbsp;socket&nbsp;file&nbsp;<BR>descriptor.&nbsp;You&nbsp;comply&nbsp;and&nbsp;call&nbsp;socket().&nbsp;Next,&nbsp;the&nbsp;user&nbsp;tells&nbsp;you&nbsp;to&nbsp;<BR>connect&nbsp;to&nbsp;&quot;132.241.5.10&quot;&nbsp;on&nbsp;port&nbsp;&quot;23&quot;&nbsp;(the&nbsp;standard&nbsp;telnet&nbsp;port.)&nbsp;Oh&nbsp;my&nbsp;<BR>God!&nbsp;What&nbsp;do&nbsp;you&nbsp;do&nbsp;now?&nbsp;<BR>Lucky&nbsp;for&nbsp;you,&nbsp;program,&nbsp;you're&nbsp;now&nbsp;perusing&nbsp;the&nbsp;section&nbsp;on&nbsp;connect()--how&nbsp;to&nbsp;<BR>&nbsp;<BR>connect&nbsp;to&nbsp;a&nbsp;remote&nbsp;host.&nbsp;You&nbsp;read&nbsp;furiously&nbsp;onward,&nbsp;not&nbsp;wanting&nbsp;to&nbsp;<BR>disappoint&nbsp;your&nbsp;user...&nbsp;<BR>The&nbsp;connect()&nbsp;call&nbsp;is&nbsp;as&nbsp;follows:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/types.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;connect(int&nbsp;sockfd,&nbsp;struct&nbsp;sockaddr&nbsp;*serv_addr,&nbsp;int&nbsp;addrlen);&nbsp;<BR>sockfd&nbsp;is&nbsp;our&nbsp;friendly&nbsp;neighborhood&nbsp;socket&nbsp;file&nbsp;descriptor,&nbsp;as&nbsp;returned&nbsp;by&nbsp;<BR>the&nbsp;socket()&nbsp;call,&nbsp;serv_addr&nbsp;is&nbsp;a&nbsp;struct&nbsp;sockaddr&nbsp;containing&nbsp;the&nbsp;destination&nbsp;<BR>&nbsp;<BR>port&nbsp;and&nbsp;IP&nbsp;address,&nbsp;and&nbsp;addrlen&nbsp;can&nbsp;be&nbsp;set&nbsp;to&nbsp;sizeof(struct&nbsp;sockaddr).&nbsp;<BR>Isn't&nbsp;this&nbsp;starting&nbsp;to&nbsp;make&nbsp;more&nbsp;sense?&nbsp;Let's&nbsp;have&nbsp;an&nbsp;example:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;string.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/types.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;sys/socket.h&gt;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;DEST_IP&nbsp;&nbsp;&nbsp;&quot;132.241.5.10&quot;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;DEST_PORT&nbsp;23&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;main()&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;sockfd;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;sockaddr_in&nbsp;dest_addr;&nbsp;&nbsp;&nbsp;/*&nbsp;will&nbsp;hold&nbsp;the&nbsp;destination&nbsp;addr&nbsp;*/&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sockfd&nbsp;=&nbsp;socket(AF_INET,&nbsp;SOCK_STREAM,&nbsp;0);&nbsp;/*&nbsp;do&nbsp;some&nbsp;error&nbsp;checking!&nbsp;<BR>&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest_addr.sin_family&nbsp;=&nbsp;AF_INET;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;host&nbsp;byte&nbsp;order&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest_addr.sin_port&nbsp;=&nbsp;htons(DEST_PORT);&nbsp;/*&nbsp;short,&nbsp;network&nbsp;byte&nbsp;order&nbsp;&nbsp;<BR>*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest_addr.sin_addr.s_addr&nbsp;=&nbsp;inet_addr(DEST_IP);&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -