TCP鐨勪笁娆℃彙鎵

鏈嶅姟绔噯澶囪繛鎺ョ殑杩囩▼

鍒涘缓濂楁帴瀛

瑕佸垱寤轰竴涓彲鐢ㄧ殑濂楁帴瀛楋紝闇瑕佷娇鐢ㄤ笅闈㈢殑鍑芥暟

int socket(int domain, int type, int protocol)

domain灏辨槸鎸嘝F_INET,PF_INET6浠ュ強PF_LOCAL绛夛紝琛ㄧず浠涔堟牱鐨勫鎺ュ瓧

type鍙敤鐨勫兼槸锛
– SOCK_STREAM:琛ㄧず鐨勬槸瀛楄妭娴侊紝瀵瑰簲tcp
– SOCK_DGRAM: 琛ㄧず鐨勬槸鏁版嵁鎶ワ紝瀵瑰簲udp
– SOCK_RAW:琛ㄧず鐨勬槸鍘熷濂楁帴瀛
鍙傛暟protocol鍘熸湰鏄敤鏉ユ寚瀹氶氫俊鍗忚鐨勶紝鐜板湪鍩烘湰搴熷純銆傚洜涓哄崗璁凡缁忛氳繃鍓嶉潰涓や釜鍙傛暟鎸囧畾瀹屾垚锛屾墍浠ュ啓0灏辫銆

bind锛氳瀹氱數璇濆彿鐮

鍒涘缓鍑烘潵鐨勫鎺ュ瓧濡傛灉闇瑕佽鍒汉浣跨敤锛屽氨闇瑕佽皟鐢╞ind鍑芥暟鎶婂鎺ュ瓧鍜屽鎺ュ瓧鍦板潃缁戝畾銆

bind(int fd, sockaddr * addr, socklen_t len)

bind绗簩涓弬鏁版槸閫氱敤鍦板潃sockaddraddr,杩欓噷鏈変竴涓湴鏂瑰煎緱娉ㄦ剰锛岄偅灏辨槸铏界劧鎺ユ敹鐨勬槸閫氱敤鍦板潃鏍煎紡锛屽疄闄呬笂浼犲叆鐨勫弬鏁板彲鑳芥槸ipv4锛宨pv6鎴栬呮湰鍦板鎺ュ瓧鏍煎紡銆傛牴鎹甽en瀛楁鍒ゆ柇浼犲叆鐨刟ddr璇ユ庝箞瑙f瀽锛宭en瀛楁琛ㄧず鐨勬槸浼犲叆鐨勫湴鍧闀垮害锛屽畠鏄竴涓彲鍙樺笺
鍙互鐞嗚В涓
bind(int fd, void * addr, socklen_t len)
涓嶈繃bsd璁捐濂楁帴瀛楀ぇ绾︽槸1982骞达紝閭d釜鏃跺檆璇█杩樻病鏈塿oid
鐨勬敮鎸併備负浜嗚В鍐宠繖涓棶棰橈紝BSD鐨勮璁¤呬滑鍒涘缓鎬х殑璁捐浜嗛氱敤鍦板潃鏍煎紡鏉ヤ綔涓烘敮鎸乥ind鍜宎ccept绛夎繖浜涘嚱鏁扮殑鍙傛暟銆

瀵逛簬浣跨敤鑰呮潵璇达紝姣忔寰愬▍灏唅pv4锛宨pv6鎴栬呮湰鍦板鎺ュ瓧杞寲涓洪氱敤濂楁帴瀛楁牸寮忥紝灏卞儚甯岃繄绾崇殑ipv4濂楁帴瀛楀湴鍧鏍煎紡鐨勪緥瀛愪竴鏍凤細

struct sockaddr_in name;
bind (sock, (struct sockaddr *) &name, sizeof (name)

瀵逛簬瀹炵幇鑰呮潵璇达紝鍙牴鎹鍦板潃鐨勫墠涓や釜瀛楄妭鍒ゆ柇鍑烘槸鍝鍦板潃锛屼负浜嗗鐞嗛暱搴﹀彲鍙樼殑缁撴瀯锛岄渶瑕佽鍙栧嚱鏁扮殑绗笁涓弬鏁帮紝涔熷氨鏄痩en瀛楁銆

鎴戜滑鍙互鎶婂湴鍧璁剧疆鎴愭湰鍦扮殑ip鍦板潃锛岃繖鐩稿綋浜庡憡璇夋搷浣滅郴缁熷唴鏍革紝浠呬粎瀵圭洰鏍噄p鏄湰鏈篿p鍦板潃鐨刬p鍖呰繘琛屽鐞嗭紝閫氳繃缁熼厤鍦板潃鐨勮缃
瀵逛簬ipv4鐨勫湴鍧鏉ヨ锛屼娇鐢╥naddr_any鏉ュ畬鎴愮粺閰嶅湴鍧鐨勮缃
瀵逛簬ipv6鐨勫湴鍧鏉ヨ锛屼娇鐢╥n6addr_any鏉ュ畬鎴愮粺閰嶅湴鍧鐨勮缃

struct sockaddr_in name;
name.sin_addr.s_addr = htonl (INADDR_ANY); /* IPV4 閫氶厤鍦板潃 */

闄や簡鍦板潃锛岃繕鏈夌鍙o紝濡傛灉鎶婄鍙h缃负0锛屽氨鐩稿綋浜庢妸绔彛鐨勬帶鍒舵潈浜ょ粰鎿嶄綔绯荤粺鍐呮牳鏉ュ鐞嗭紝鎿嶄綔绯荤粺鍐呮牳浼氭牴鎹竴瀹氱殑绠楁硶閫夋嫨涓涓┖闂茬殑绔彛锛屽畬鎴愬鎺ュ瓧鐨勭粦瀹氥
涓涓猧pv4 tcp濂楁帴瀛楃殑渚嬪瓙

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>


int make_socket (uint16_t port)
{
  int sock;
  struct sockaddr_in name;


  /* 鍒涘缓瀛楄妭娴佺被鍨嬬殑 IPV4 socket. */
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }


  /* 缁戝畾鍒 port 鍜 ip. */
  name.sin_family = AF_INET; /* IPV4 */
  name.sin_port = htons (port);  /* 鎸囧畾绔彛 */
  name.sin_addr.s_addr = htonl (INADDR_ANY); /* 閫氶厤鍦板潃 */
  /* 鎶 IPV4 鍦板潃杞崲鎴愰氱敤鍦板潃鏍煎紡锛屽悓鏃朵紶閫掗暱搴 */
  if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
    {
      perror ("bind");
      exit (EXIT_FAILURE);
    }


  return sock
}

listen

鍒濆鍖栧垱寤虹殑濂楁帴瀛楋紝鍙互璁や负鏄竴涓”涓诲姩”濂楁帴瀛楋紝鍏剁洰鐨勬槸涔嬪悗涓诲姩鍙戣捣璇锋眰(閫氳繃璋冪敤connect鍑芥暟)锛岄氳繃listen鍑芥暟锛屽彲浠ュ皢鍘熸潵鐨”涓诲姩”濂楁帴瀛楄浆鎹负”琚姩”濂楁帴瀛楋紝鍛婅瘔鎿嶄綔绯荤粺鍐呮牳浼歩涓烘鍋氬ソ鎺ュ彈鐢ㄦ埛璇锋眰鐨勪竴鍒囧噯澶囷紝姣斿瀹屾垚杩炴帴闃熷垪銆
listen鍑芥暟
int listen (int socketfd, int backlog)
绗竴涓弬鏁皊ocketfd涓哄鎺ュ瓧鎻忚堪绗,绗簩涓弬鏁癰acklog锛屽畼鏂圭殑瑙i噴涓烘湭瀹屾垚杩炴帴闃熷垪鐨勫ぇ灏忥紝杩欎釜鍙傛暟鐨勫ぇ灏忓喅瀹氫簡鍙互鎺ユ敹鐨勫苟鍙戞暟鐩紝杩欎釜鍙傛暟瓒婂ぇ锛屽苟鍙戞暟鐩悊璁轰笂涔熶細瓒婂ぇ锛屼絾鏄弬鏁拌繃澶т篃浼氬崰鐢ㄨ繃澶氱殑绯荤粺璧勬簮锛屼竴浜涚郴缁燂紝姣斿linux骞朵笉杩愯瀵硅繖涓弬鏁拌繘琛屾敼鍙橈紝瀵逛簬backlog鏁翠釜鍙傛暟鐨勮缃湁涓浜涙渶浣冲疄璺点

accept

濂芥瘮鏈変汉鎵撶數璇濊繃鏉ワ紝闇瑕佹嬁璧疯瘽绛掑紑濮嬪簲绛斻

浣滅敤灏辨槸杩炴帴寤虹珛涔嬪悗锛屾搷浣滅郴缁熷唴鏍稿拰搴旂敤绋嬪簭涔嬮棿鐨勬ˉ姊

int accept(int listensockfd, struct sockaddr *cliaddr, socklen_t *addrlen)

杩欓噷涓瀹氳娉ㄦ剰鏈変袱涓鎺ュ瓧鎻忚堪瀛楋紝绗竴涓槸鐩戝惉濂楁帴瀛楁弿杩板瓧listensockfd,瀹冩槸浣滀负杈撳叆鍙傛暟瀛樺湪鐨勶紱绗簩涓槸杩斿洖鐨勫凡杩炴帴濂楁帴瀛楁弿杩板瓧銆

瀹㈡埛绔彂璧疯繛鎺ョ殑杩囩▼

鍓嶉潰璁茶堪鐨刡ind锛宭isten浠ュ強accept鐨勮繃绋嬶紝鏄吀鍨嬬殑鏈嶅姟鍣ㄧ鐨勮繃绋嬨
绗竴姝ヨ繕鏄竴鏍凤紝寤虹珛涓涓鎺ュ瓧銆備笉涓鏍风殑鏄

connect:鎷ㄦ墦鐢佃瘽

瀹㈡埛绔拰鏈嶅姟鍣ㄧ鐨勮繛鎺ュ缓绔嬶紝鏄氳繃connect鍑芥暟瀹屾垚鐨

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen)

鍑芥暟鐨勭涓涓弬鏁皊ockfd鏄繛鎺ュ鎺ュ瓧锛岄氳繃鍓嶉潰璁茶堪鐨剆ocket鍑芥暟鍒涘缓銆傜浜屼釜锛岀涓変釜鍙傛暟servaddr鍜宎ddrlen鍒嗗埆浠h〃鎸囧悜濂楁帴瀛楀湴鍧缁撴瀯鐨勬寚閽堝拰璇ョ粨鏋勭殑澶у皬銆傚鎺ュ瓧鍦板潃缁撴瀯蹇呴』鍚湁鏈嶅姟鍣ㄧ殑ip鍦板潃鍜岀鍙e彿銆

瀹㈡埛鍦ㄨ皟鐢ㄥ嚱鏁癱onnect鍓嶄笉蹇呴潪寰楄皟鐢╞ind鍑芥暟锛屽洜涓哄鏋滈渶瑕佺殑璇濓紝鍐呮牳浼氱‘瀹氭簮ip鍦板潃锛屽苟鎸夌収涓瀹氱殑绠楁硶閫夋嫨涓涓复鏃剁鍙f墍璋撴簮绔彛銆
濡傛灉鏄痶cp濂楁帴瀛楋紝閭d箞璋冪敤connect鍑芥暟灏嗘縺鍙憈cp鐨勪笁娆℃彙鎵嬭繃绋嬶紝鑰屼笖浠呭湪杩炴帴寤虹珛鎴愬姛鎴栧嚭閿欐墠杩斿洖銆
鍏朵腑鍑洪敊杩斿洖鍙兘鏈変互涓嬪嚑绉嶆儏鍐碉細
1. 涓夋鎻℃墜鏃犳硶寤虹珛锛屽鎴风鍙戝嚭鐨剆yn鍖呮病鏈変换浣曠浉搴旓紝浜庢槸杩斿洖timeout閿欒锛岃繖绉嶆儏鍐垫瘮杈冨父瑙佺殑鍘熷洜鏄搴旂殑鏈嶅姟绔痠p鍐欓敊銆
2. 瀹㈡埛绔敹鍒颁簡RST(澶嶄綅)鍥炵瓟锛岃繖鏃跺欏鎴风浼氱珛鍗宠繑鍥瀋onnection refused閿欒銆傝繖寮犳儏鍐垫瘮杈冨父瑙佷簬瀹㈡埛绔彂閫佽繛鎺ヨ姹傛椂鐨勮姹傜鍙e啓閿欙紝鍥犱负RST鏄痶cp鍦ㄥ彂鐢熼敊璇椂鍙戦佺殑涓绉峵cp鍒嗚妭銆備骇鐢烺ST鐨勪笁涓潯浠舵槸锛氱洰鐨勫湴涓烘煇绔彛鐨凷YN鍒拌揪锛岀劧鑰岃绔彛涓婃病鏈夋鍦ㄧ洃鍚殑鏈嶅姟鍣(濡傚墠鎵杩)锛汿CP鎯冲彇娑堜竴涓凡鏈夎繛鎺ワ紱TCP鎺ユ敹鍒颁竴涓牴鏈笉瀛樺湪鐨勮繛鎺ヤ笂鐨勫垎鑺傘
3. 瀹㈡埛鍙戝嚭鐨凷YN鍖呭湪缃戠粶涓婂紩璧蜂簡”destination unreachable”,鍗崇洰鐨勪笉鍙揪鐨勯敊璇紝杩欑鎯呭喌姣旇緝甯歌鐨勫師鍥犳槸瀹㈡埛绔拰鏈嶅姟绔矾鐢变笉鍚屻

钁楀悕鐨凾CP涓夋鎻℃墜

瀹㈡埛绔 鏈嶅姟鍣
socket,connect(闃诲)(涓诲姩鎵撳紑)SYN_SENT SYN j socket,bind,listen(琚姩鎵撳紑)accept(闃诲)SYN_RCVD SYN k,ACK j+1
connect杩斿洖 ESTABLISED ACK k+1 accept杩斿洖 read闃诲 ESTABLISED

闃诲寮忥紝灏辨槸璋冪敤鍙戣捣鍚庝笉浼氱洿鎺ヨ繑鍥烇紝鍙堟搷浣滅郴缁熷唴鏍稿鐞嗕箣鍚庢墠浼氳繑鍥烇紝鐩稿鐨勶紝杩樻湁涓绉嶅彨鍋氶潪闃诲寮忕殑銆

TCP涓夋鎻℃墜鐨勮В璇

涓寮濮嬫湇鍔″櫒閫氳繃socket, bind鍜宭isten瀹屾垚浜嗚鍔ㄥ鎺ュ瓧鐨勫噯澶囧伐浣滐紝琚姩鐨勬剰鎬濆氨鏄瓑鐫鍒汉鏉ヨ繛鎺ワ紝鐒朵箮璋冪敤accept锛屾晳鎶ら樆濉炲湪杩欓噷锛岀瓑寰呭鎴风鐨勮繛鎺ユ潵涓达紱瀹㈡埛绔氳繃socket鍜宑onnect鍑芥暟涔嬪悗锛屼篃浼氶樆濉炪傛帴涓嬫潵鐨勪簨鎯呮槸鐢辨搷浣滅郴缁熷唴鏍稿畬鎴愶紝鏇村叿浣撶殑鏉ヨ锛屾槸鎿嶄綔绯荤粺鍐呮牳缃戠粶鍗忚鏍堝湪宸ヤ綔銆
1. 瀹㈡埛绔殑鍗忚鏍堝悜鏈嶅姟鍣ㄧ鍙戦佷簡SYN鍖咃紝骞跺憡璇夋湇鍔″櫒绔綋鍓嶅彂閫佸簭鍒楀彿j锛屽鎴风杩涘叆SYNC_SENT鐘舵侊紱
2. 鏈嶅姟鍣ㄧ鐨勫崗璁爤鏀跺埌杩欎釜鍖呬箣鍚庯紝鍜屽鎴风杩涜ACK搴旂瓟锛屽簲绛旂殑鍊间负j+1锛岃〃绀哄SYN鍖卝鐨勭‘璁わ紝鍚屾椂鏈嶅姟鍣ㄤ篃鍙戦佷竴涓猄YN鍖咃紝鍛婅瘔瀹㈡埛绔綋鍓嶆垜鐨勫彂閫佸簭鍒楀彿涓簁锛屾湇鍔″櫒绔繘鍏YNC_RCVD鐘舵侊紱
3. 瀹㈡埛绔崗璁爤鏀跺埌ACK涔嬪悗锛屼娇寰楀簲鐢ㄧ▼搴忎粠connect璋冪敤杩斿洖锛岃〃绀哄鎴风鍒版湇鍔″櫒绔殑鍗曞悜杩炴帴寤虹珛鎴愬姛锛屽鎴风鐨勭姸鎬佷负ESTABLISHED锛屽悓鏃跺鎴风鍗忚鏍堜篃浼氬鏈嶅姟鍣ㄧ鐨凷YN鍖呰繘琛屽簲绛旓紝搴旂瓟鏁版嵁涓簁+1锛
4. 搴旂瓟鍖呰揪鍒版湇鍔″櫒绔悗锛屾湇鍔″櫒绔崗璁爤浣垮緱accept闃诲璋冪敤杩斿洖锛岃繖涓椂鍊欐湇鍔″櫒绔埌瀹㈡埛绔殑鍗曞悜杩炴帴涔熷缓绔嬫垚鍔燂紝鏈嶅姟鍣ㄧ涔熻繘鍏STRABLISHED鐘舵併

All posts

Other pages

鍙戣〃璇勮

鐢靛瓙閭欢鍦板潃涓嶄細琚叕寮銆 蹇呭~椤瑰凡鐢*鏍囨敞