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