socket編程udp
1. TCP 鍜 UDP 鍦╯ocket緙栫▼涓鐨勫尯鍒
涓銆乀CP涓嶶DP鐨勫尯鍒
鍩轟簬榪炴帴涓庢棤榪炴帴
銆銆瀵圭郴緇熻祫婧愮殑瑕佹眰錛圱CP杈冨氾紝UDP灝戱級
銆銆UDP紼嬪簭緇撴瀯杈冪畝鍗
銆銆嫻佹ā寮忎笌鏁版嵁鎶ユā寮
銆銆TCP淇濊瘉鏁版嵁姝g『鎬э紝UDP鍙鑳戒涪鍖
銆銆TCP淇濊瘉鏁版嵁欏哄簭錛孶DP涓嶄繚璇
銆銆閮ㄥ垎婊¤凍浠ヤ笅鍑犵偣瑕佹眰鏃訛紝搴旇ラ噰鐢║DP 闈㈠悜鏁版嵁鎶ユ柟寮 緗戠粶鏁版嵁澶у氫負鐭娑堟伅
銆銆鎷ユ湁澶ч噺Client
銆銆瀵規暟鎹瀹夊叏鎬ф棤鐗規畩瑕佹眰
銆銆緗戠粶璐熸媴闈炲父閲嶏紝浣嗗瑰搷搴旈熷害瑕佹眰楂
銆銆鍏蜂綋緙栫▼鏃剁殑鍖哄埆 socket()鐨勫弬鏁頒笉鍚
銆銆UDP Server涓嶉渶瑕佽皟鐢╨isten鍜宎ccept
銆銆UDP鏀跺彂鏁版嵁鐢╯endto/recvfrom鍑芥暟
銆銆TCP錛氬湴鍧淇℃伅鍦╟onnect/accept鏃剁『瀹
銆銆UDP錛氬湪sendto/recvfrom鍑芥暟涓姣忔″潎 闇鎸囧畾鍦板潃淇℃伅
銆銆UDP錛歴hutdown鍑芥暟鏃犳晥
浜屻乵an----socket
銆銆銆銆閫氳繃鏌ョ湅socket鐨刴an鎵嬪唽鍙浠ョ湅鍒皊ocket鍑芥暟鐨勭涓涓鍙傛暟鐨勫煎彲浠ヤ負涓嬮潰榪欎簺鍊礆細
銆銆Name Purpose
銆銆PF_UNIX, PF_LOCAL Local communication
銆銆PF_INET IPv4 Internet protocols
銆銆PF_INET6 IPv6 Internet protocols
銆銆PF_IPX IPX - Novell protocols
銆銆PF_NETLINK Kernel user interface device
銆銆PF_X25 ITU-T X.25 / ISO-8208 protocol
銆銆PF_AX25 Amateur radio AX.25 protocol
銆銆PF_ATMPVC Access to raw ATM PVCs
銆銆PF_APPLETALK Appletalk
銆銆PF_PACKET Low level packet interface
涓夈佺紪紼嬪尯鍒
閫氬父鎴戜滑鍦ㄨ村埌緗戠粶緙栫▼鏃墮粯璁ゆ槸鎸嘥CP緙栫▼錛屽嵆鐢ㄥ墠闈㈡彁鍒扮殑socket鍑芥暟鍒涘緩涓涓猻ocket鐢ㄤ簬TCP閫氳錛屽嚱鏁板弬鏁版垜浠閫氬父濉涓篠OCK_STREAM銆傚嵆socket(PF_INET, SOCK_STREAM, 0)錛岃繖琛ㄧず寤虹珛涓涓猻ocket鐢ㄤ簬嫻佸紡緗戠粶閫氳銆
銆 SOCK_STREAM榪欑嶇殑鐗圭偣鏄闈㈠悜榪炴帴鐨勶紝鍗蟲瘡嬈℃敹鍙戞暟鎹涔嬪墠蹇呴』閫氳繃connect寤虹珛榪炴帴錛屼篃鏄鍙屽悜鐨勶紝鍗充換浣曚竴鏂歸兘鍙浠ユ敹鍙戞暟鎹錛屽崗璁鏈韜鎻愪緵浜嗕竴浜涗繚闅滄満鍒朵繚璇佸畠鏄鍙闈犵殑銆佹湁搴忕殑錛屽嵆姣忎釜鍖呮寜鐓у彂閫佺殑欏哄簭鍒拌揪鎺ユ敹鏂廣
銆銆鑰孲OCK_DGRAM榪欑嶆槸User Datagram Protocol鍗忚鐨勭綉緇滈氳錛屽畠鏄鏃犺繛鎺ョ殑錛屼笉鍙闈犵殑錛屽洜涓洪氳鍙屾柟鍙戦佹暟鎹鍚庝笉鐭ラ亾瀵規柟鏄鍚﹀凡緇忔敹鍒版暟鎹錛屾槸鍚︽e父鏀跺埌鏁版嵁銆備換浣曚竴鏂瑰緩絝嬩竴涓猻ocket浠ュ悗灝卞彲浠ョ敤sendto鍙戦佹暟鎹錛屼篃鍙浠ョ敤recvfrom鎺ユ敹鏁版嵁銆傛牴鏈涓嶅叧蹇冨規柟鏄鍚﹀瓨鍦錛屾槸鍚﹀彂閫佷簡鏁版嵁銆傚畠鐨勭壒鐐規槸閫氳閫熷害姣旇緝蹇銆傚ぇ瀹墮兘鐭ラ亾TCP鏄瑕佺粡榪囦笁嬈℃彙鎵嬬殑錛岃孶DP娌℃湁銆
銆銆鍩轟簬涓婅堪涓嶅悓錛孶DP鍜孴CP緙栫▼姝ラや篃鏈変簺涓嶅悓錛屽備笅錛
銆銆TCP緙栫▼鐨勬湇鍔″櫒絝涓鑸姝ラゆ槸錛
銆銆1銆佸壋寤轟竴涓猻ocket錛岀敤鍑芥暟socket()錛
銆銆2銆佽劇疆socket灞炴э紝鐢ㄥ嚱鏁皊etsockopt(); * 鍙閫
銆銆3銆佺粦瀹欼P鍦板潃銆佺鍙g瓑淇℃伅鍒皊ocket涓婏紝鐢ㄥ嚱鏁癰ind();
銆銆4銆佸紑鍚鐩戝惉錛岀敤鍑芥暟listen()錛
銆銆5銆佹帴鏀跺㈡埛絝涓婃潵鐨勮繛鎺ワ紝鐢ㄥ嚱鏁癮ccept()錛
銆銆6銆佹敹鍙戞暟鎹錛岀敤鍑芥暟send()鍜宺ecv()錛屾垨鑰卹ead()鍜寃rite();
銆銆7銆佸叧闂緗戠粶榪炴帴錛
銆銆8銆佸叧闂鐩戝惉錛
銆銆TCP緙栫▼鐨勫㈡埛絝涓鑸姝ラゆ槸錛
銆銆1銆佸壋寤轟竴涓猻ocket錛岀敤鍑芥暟socket()錛
銆銆2銆佽劇疆socket灞炴э紝鐢ㄥ嚱鏁皊etsockopt();* 鍙閫
銆銆3銆佺粦瀹欼P鍦板潃銆佺鍙g瓑淇℃伅鍒皊ocket涓婏紝鐢ㄥ嚱鏁癰ind();* 鍙閫
銆銆4銆佽劇疆瑕佽繛鎺ョ殑瀵規柟鐨処P鍦板潃鍜岀鍙g瓑灞炴э紱
銆銆5銆佽繛鎺ユ湇鍔″櫒錛岀敤鍑芥暟connect()錛
銆銆6銆佹敹鍙戞暟鎹錛岀敤鍑芥暟send()鍜宺ecv()錛屾垨鑰卹ead()鍜寃rite();
銆銆7銆佸叧闂緗戠粶榪炴帴錛
銆銆涓庝箣瀵瑰簲鐨刄DP緙栫▼姝ラよ佺畝鍗曡稿氾紝鍒嗗埆濡備笅錛
銆銆UDP緙栫▼鐨勬湇鍔″櫒絝涓鑸姝ラゆ槸錛
銆銆1銆佸壋寤轟竴涓猻ocket錛岀敤鍑芥暟socket()錛
銆銆2銆佽劇疆socket灞炴э紝鐢ㄥ嚱鏁皊etsockopt();* 鍙閫
銆銆3銆佺粦瀹欼P鍦板潃銆佺鍙g瓑淇℃伅鍒皊ocket涓婏紝鐢ㄥ嚱鏁癰ind();
銆銆4銆佸驚鐜鎺ユ敹鏁版嵁錛岀敤鍑芥暟recvfrom();
銆銆5銆佸叧闂緗戠粶榪炴帴錛
銆銆UDP緙栫▼鐨勫㈡埛絝涓鑸姝ラゆ槸錛
銆銆1銆佸壋寤轟竴涓猻ocket錛岀敤鍑芥暟socket()錛
銆銆2銆佽劇疆socket灞炴э紝鐢ㄥ嚱鏁皊etsockopt();* 鍙閫
銆銆3銆佺粦瀹欼P鍦板潃銆佺鍙g瓑淇℃伅鍒皊ocket涓婏紝鐢ㄥ嚱鏁癰ind();* 鍙閫
銆銆4銆佽劇疆瀵規柟鐨処P鍦板潃鍜岀鍙g瓑灞炴;
銆銆5銆佸彂閫佹暟鎹錛岀敤鍑芥暟sendto();
銆銆6銆佸叧闂緗戠粶榪炴帴錛
2. TCP 和 UDP 在socket編程中的區別
UDP和TCP編程步驟也有些不同,如下:
TCP編程的伺服器端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt(); * 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();
4、開啟監聽,用函數listen();
5、接收客戶端上來的連接,用函數accept();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網路連接;
8、關閉監聽;
TCP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();* 可選
4、設置要連接的對方的IP地址和埠等屬性;
5、連接伺服器,用函數connect();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網路連接;
與之對應的UDP編程步驟要簡單許多,分別如下:
UDP編程的伺服器端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();
4、循環接收數據,用函數recvfrom();
5、關閉網路連接;
UDP編程的客戶端一般步驟是:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、埠等信息到socket上,用函數bind();* 可選
4、設置對方的IP地址和埠等屬性;
5、發送數據,用函數sendto();
6、關閉網路連接;
3. C語言 UDP socket 簡單客戶端 編程,急
提一下,你那個地址不好用,換成了127.0.0.1,埠可以用,完全按照要求寫的,編譯沒錯誤,調試通過:
gcc server.c -o server
gcc client.c -o client
打開2個控制台:一個運行 ./server 另一個運行 ./client
server.c:
========================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#define BUFFERSIZE 1024
typedef struct sockaddr SA;
int main(void)
{
char buf[BUFFERSIZE];
struct sockaddr_in addr_s;
struct sockaddr_in addr_c;
int sockfd;
socklen_t length;
int i;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1)
{
perror("socket fail");
return -1;
}
memset(&addr_s,0,sizeof(addr_s));
addr_s.sin_family = AF_INET;
addr_s.sin_addr.s_addr = inet_addr("127.0.0.1");
addr_s.sin_port = htons(31180);
if(bind(sockfd,(SA *)&addr_s,sizeof(addr_s)) == -1)
{
perror("bind fail");
return -1;
}
length = sizeof(addr_c);
memset(buf,'\0',sizeof(buf));
if(recvfrom(sockfd,buf,sizeof(buf),0
,(SA *)&addr_c,&length) == -1)
{
perror("recvfrom fail");
}
printf("recvfrom client:%s\n",buf);
sendto(sockfd,buf,sizeof(buf),0,(SA *)&addr_c,sizeof(addr_c));
close(sockfd);
}
====================================
client.c:
====================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#define BUFFERSIZE 1024
typedef struct sockaddr SA;
int main(void)
{
int sockfd;
char buf[BUFFERSIZE];
struct sockaddr_in addr_s;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1)
{
perror("socket fail");
return -1;
}
memset(&addr_s,0,sizeof(addr_s));
addr_s.sin_family = AF_INET;
addr_s.sin_addr.s_addr = inet_addr("127.0.0.1");
addr_s.sin_port = htons(31180);
memset(buf,'\0',sizeof(buf));
sprintf(buf,"abcde");
if(sendto(sockfd,buf,sizeof(buf)
,0,(SA *)&addr_s,sizeof(addr_s)) < 0)
{
perror("sendto fail");
}
memset(buf,'\0',sizeof(buf));
recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL);
printf("recvfrom server:%s\n",buf);
close(sockfd);
}
4. 簡述基於TCP和UDP的Socket編程的異同
Socket有兩種主要的操作方式:面向連接的和無連接的。無連接的操作使用UDP數據報協議,這個操作不需要連接一個目的的socket,它只是簡單地投出數據報,快速高效,但缺少數據安全性。面向連接的操作使用TCP協議,一個這個模式的socket必須在發送數據之前與目的地的socket取得一個連接,一旦連接建立了,socket就可以使用一個流介面:打開-讀-寫-關閉,所有的發送的信息都會在另一端以同樣的順序被接收,面向連接的操作比無連接的操作效率要低,但數據的安全性更高。基於TCP的socket編程是採用的流式套接字(SOCK_STREAM)。基於UDP採用的數據報套接字(SOCK_DGRAM).
流式套接字的設計是針對面向連接的網路應用,在數據傳輸之前需要預先建立連接,在數據傳輸過程中需要維持連接,在數據傳輸結束後需要釋放連接。由於採用校驗和、確認與超時等差錯控制手段,因此流式套接字可以保證數據傳輸的正確性。
數據報套接字(SOCK_DGRAM)提供無連接的、不可靠的數據傳輸服務,實際上它是基於TCP/IP協議族中的UDP協議實現的。數據報套接字提供無序、有差錯與有重復的數據流服務。數據報套接字的設計是針對無連接的網路應用,在數據傳輸之前不需要預先建立連接。由於只採用很有限的差錯控制手段,因此數據報套接字無法保證數據傳輸的正確性。
5. CSocket之UDP編程
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
SOCKET sersocket=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN seraddr;
seraddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(5000);
bind(sersocket,(SOCKADDR*)&seraddr,sizeof(SOCKADDR));
SOCKADDR clientaddr;
int len=sizeof(SOCKADDR);
char revbuf[100];
char sendbuf[100];
recvfrom(sersocket,revbuf,100,0,(SOCKADDR*)&clientaddr,&len);
printf("%s\n",revbuf);
scanf("%s",&sendbuf);
sendto(sersocket,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&clientaddr,len);
closesocket(sersocket);
WSACleanup();
}
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
SOCKET sockclient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN clientaddr;
clientaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
clientaddr.sin_family=AF_INET;
clientaddr.sin_port=htons(5000);
int len=sizeof(SOCKADDR);
char revbuf[100];
char sendbuf[100];
printf("請輸入內容:\n");
while(1)
{
scanf("%s",&sendbuf);
sendto(sockclient,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&clientaddr,len);
recvfrom(sockclient,revbuf,100,0,(SOCKADDR*)&clientaddr,&len);
printf("%s\n",revbuf);
}
closesocket(sockclient);
WSACleanup();
}
大同小異,CSocket只是進行了封裝而已,原理是一樣的,編程要思路靈活才行。
6. python中使用socket編程,如何能夠通過UDP傳遞一個列表類型的數據
Python中的 list 或者 dict 都可以轉成JSON字元串來發送,接收後再轉回來。
首先
importjson
然後,把 list 或 dict 轉成 JSON
json_string=json.mps(list_or_dict)
如果你用的是Python3,這里的 json_string 會是 str 類型(即Python2的unicode類型),可能需要編碼一下:
if type(json_string) == six.text_type:
json_string = json_string.encode('UTF-8')
用socket發送過去,例如
s.sendto(json_string,address)
對方用socket接收,例如
json_string,addr=s.recvfrom(2048)
把JSON轉成 list 或 dict
list_or_dict=json.loads(json_string)
下面是個完整的例子:
client.py
#!/usr/bin/envpython
#-*-coding:UTF-8-*-
importsocket
importjson
importsix
address=('127.0.0.1',31500)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
mylist=[1,2,3,4,5,6,7,8,9,10]
json_string=json.mps(mylist)
iftype(json_string)==six.text_type:
json_string=json_string.encode('UTF-8')
s.sendto(json_string,address)
s.close()
server.py
#!/usr/bin/envpython
#-*-coding:UTF-8-*-
importsocket
importjson
address=('127.0.0.1',31500)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(address)
json_string,addr=s.recvfrom(2048)
mylist=json.loads(json_string)
print(mylist)
s.close()
請先運行server.py,再運行client.py