java socket发送定长报文_socket编程
生活随笔
收集整理的這篇文章主要介紹了
java socket发送定长报文_socket编程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1.socket編程的概念
- socket通常也稱作"套接字",用于描述IP地址和端口,是一個通信鏈的句柄,應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求;
- socket起源于Unix,而Unix/Linux基本哲學(xué)之一就是“一切皆文件”,socket就是該模式的一個實(shí)現(xiàn),socket即是一種特殊的文件,一些socket函數(shù)就是對其進(jìn)行的操作;
- 線程之間的通信形式有:event時間,lock鎖,信號量,queue隊列等,而進(jìn)程之間的通信,一般使用套接字,套接字的IPC方式使得跨平臺之間的進(jìn)程通信成為可能,最早的socket是在BSD-Unix平臺上發(fā)布,最終成為了行業(yè)標(biāo)準(zhǔn),使得計算機(jī)之間的通信變得非常簡單;
2.socket( )類詳解
- 套接字格式:socket(family, type[,protocal])使用給定的套接字、套接字類型、協(xié)議編號(默認(rèn)為0)來創(chuàng)建套接字 ;
- socket.AF_UNIX:用于同一臺機(jī)器上的進(jìn)程通信(既本機(jī)通信);
- socket.AF_INET:用于服務(wù)器與服務(wù)器之間的網(wǎng)絡(luò)通信;
- socket.AF_INET6:基于IPV6方式的服務(wù)器與服務(wù)器之間的網(wǎng)絡(luò)通信;
- socket.SOCK_STREAM:基于TCP的流式socket通信;
- socket.SOCK_DGRAM:基于UDP的數(shù)據(jù)報式socket通信;
- socket.SOCK_RAW:原始套接字,普通的套接字無法處理ICMP、IGMP等網(wǎng)絡(luò)報文,而SOCK_RAW可以,其次SOCK_RAW也可以處理特殊的IPV4報文,此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構(gòu)造IP頭;
- socket.SOCK_SEQPACKET:可靠的連續(xù)數(shù)據(jù)包服務(wù);
3.如何編寫服務(wù)器socket端
接下來我們講解一下TCP服務(wù)端和TCP客戶端代碼示例,大家記得看代碼的注釋,方便大家理解代碼:
# TCP服務(wù)端代碼示例import socketfrom pprint import pprint# 創(chuàng)建TCP連接socket_instance = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# bind方法的參數(shù)是ip和端口組成的元組表示addresssocket_instance.bind(('127.0.0.1', 9000))# 操作系統(tǒng)可以掛起的最大連接數(shù),如果同一時間的連接數(shù)超過5,拒絕其他的連接socket_instance.listen(5)# 死循環(huán),循環(huán)接收新的客戶端連接while True: # 接收客戶端的請求,且獲取新socket對象和客戶端信息 new_socket, client_addr = socket_instance.accept() # 阻塞,等待握手 # 循環(huán)接收已連接的客戶端發(fā)送的數(shù)據(jù) while True: # 從緩存區(qū)中讀取1024字節(jié)信息 ,使用decode()方法進(jìn)行解碼 data = new_socket.recv(1024).decode() # 阻塞的 # 返回客戶端的一下信息 pprint(data) # 返回客戶端地址 ('127.0.0.1', 51978) pprint(client_addr) # 把服務(wù)器的數(shù)據(jù)發(fā)送回客戶端,使用encode()方法把字符串編碼成二進(jìn)制 new_socket.sendall('服務(wù)器端已經(jīng)拿到你的消息'.encode())# TCP客戶端代碼實(shí)現(xiàn)import socket# 創(chuàng)建TCP連接socket_instance = socket.socket(socket.AF_INET, socket.SOCK_STREAM)socket_instance.connect(('127.0.0.1', 9000)) # 進(jìn)行三次握手while True: cmd = input("請輸入您想說的話:") socket_instance.send(cmd.encode()) # 把數(shù)據(jù)發(fā)送到服務(wù)端 data = socket_instance.recv(1024) print(data.decode())因?yàn)榭赡艽a格式會亂,所以放上代碼的圖片,代碼格式參照圖片中的
TCP的代碼圖片
現(xiàn)在我們已經(jīng)把TCP的服務(wù)端和客戶端都寫好了(寫在兩個不同的.py文件中),那我們來運(yùn)行代碼看一下效果,首先運(yùn)行服務(wù)器端代碼的.py文件(鼠標(biāo)右鍵->Run test.py),然后再運(yùn)行客戶端代碼(鼠標(biāo)右鍵->Run test1.py),客戶端會提示要我們輸入想說的話,如圖:
客戶端打印.jpg
服務(wù)端打印.jpg
需要注意的是我們不能通過TCP的客戶端連接UDP服務(wù)器,也不能通過UDP的客戶端連接TCP的服務(wù)器,也就是客戶端和服務(wù)端的socket協(xié)議必須一樣
4.UDP服務(wù)器和客戶端端代碼實(shí)現(xiàn)
# UDP服務(wù)器端代碼實(shí)現(xiàn)import socket# 創(chuàng)建UDP連接socket_instance = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)socket_instance.bind(('127.0.0.1', 9000))# 循環(huán)接收新的客戶端連接while True: # 接收客戶端的請求,且獲取新socket對象和客戶端信息 data, client_addr = socket_instance.recvfrom(1024) print(data.decode()) socket_instance.sendto('Server has receive your data'.encode(), client_addr)# UDP客戶端代碼實(shí)現(xiàn)import socket# 創(chuàng)建socket實(shí)例socket_instance = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)while True: data = input("請輸入您想說的話:") socket_instance.sendto(data.encode(), ('127.0.0.1', 9000)) data, server_addr = socket_instance.recvfrom(1024) print(data.decode())然后依次運(yùn)行服務(wù)器端代碼和客戶端代碼,步驟和TCP中的運(yùn)行差不多
UDP的代碼圖片
5.UDP 服務(wù)器端的實(shí)現(xiàn)步驟
1.創(chuàng)建 socket 對象;2.向socket 對象綁定服務(wù)器地址;3.進(jìn)入與客戶端交互數(shù)據(jù)的循環(huán)階段;4.接收客戶端發(fā)來的數(shù)據(jù)(包括 bytes 對象 data,以及客戶端的 IP 地址和端口號 addr,其中 addr 為二元組 (host, port);5.打印接收信息,表示從地址為 addr 的客戶端接收到數(shù)據(jù));6.關(guān)閉;6.UDP客戶端的實(shí)現(xiàn)步驟
1.創(chuàng)建 socket 對象;2.初始化 UDP 服務(wù)器的地址;3.進(jìn)入與服務(wù)器交互數(shù)據(jù)的循環(huán)階段;4.等待用戶輸入數(shù)據(jù);5.向服務(wù)器端發(fā)送接收數(shù)據(jù);6.關(guān)閉套接字,不再向服務(wù)器發(fā)送數(shù)據(jù);7.TCP 和UDP的區(qū)別有哪些
- TCP傳輸數(shù)據(jù)使用字節(jié)流的方式傳輸,而UDP是數(shù)據(jù)報傳輸;
- TCP對網(wǎng)絡(luò)條件要求高,而UDP更適合實(shí)時傳輸;
- TCP編程可以保證傳輸?shù)目煽啃?#xff0c;UDP則不保證;
- TCP會產(chǎn)生粘包現(xiàn)象,而UDP則容易丟包;
- TCP使用listen方法和accpet方法,而UDP不需要;
- TCP使用recv方法和send方法,而UDP使用recvfrom方法和sendto方法;
8.服務(wù)器端socket實(shí)例對象創(chuàng)建連接的方法有:
- bind():將套接字綁定到地址,在AF_INET下,以tuple(host, port)的方式傳入;
- listen():開始監(jiān)聽TCP傳入連接;
- accept():接受TCP鏈接并返回(new_socket, address),其中new_socket是新的套接字對象,可以用來接收和發(fā)送數(shù)據(jù),address是鏈接客戶端的地址;
9.客戶端socket實(shí)例對象創(chuàng)建連接的方法有:
- connect():連接到address處的套接字,一般address的格式為tuple(host, port),如果鏈接出錯,則返回socket.error錯誤;
- connect_ex():功能與s.connect(address)相同,但成功返回0,失敗返回errno的值;
10.客戶端和服務(wù)器端socket實(shí)例對象都有的方法:
- recv():接受TCP套接字的數(shù)據(jù),數(shù)據(jù)以字符串形式返回;
- send():發(fā)送TCP數(shù)據(jù),將字符串中的數(shù)據(jù)發(fā)送到鏈接的套接字,返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于string的字節(jié)大小;
- sendall():完整發(fā)送TCP數(shù)據(jù),將字符串中的數(shù)據(jù)發(fā)送到鏈接的套接字,但在返回之前嘗試發(fā)送所有數(shù)據(jù),成功返回None,失敗則拋出異常;
- recvfrom():接受UDP套接字的數(shù)據(jù);
- sendto():發(fā)送UDP數(shù)據(jù),將數(shù)據(jù)發(fā)送到套接字;
- close():關(guān)閉套接字;
- getpeername():返回套接字的遠(yuǎn)程地址;
- getsockname():返回套接字自己的地址;
- settimeout():設(shè)置套接字操作的超時時間;
- gettimeout():返回當(dāng)前超時值,單位是秒,如果沒有設(shè)置超時則返回None;
- fileno():返回套接字的文件描述;
- setblocking():如果flag為0,則將套接字設(shè)置為非阻塞模式,否則將套接字設(shè)置為阻塞模式(默認(rèn)值);
- makefile():創(chuàng)建一個與該套接字相關(guān)的文件;
- setsockopt():設(shè)置給定套接字選項的值;
- getsockopt():返回套接字選項的值;
參考:https://www.9xkd.com/user/plan-view.html?id=1374569434
總結(jié)
以上是生活随笔為你收集整理的java socket发送定长报文_socket编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷 深基 第1部分 语言入门 第2章
- 下一篇: 省选+NOI 第六部分 技巧与思想