udp編程-ag真人国际官网
1. tcp編程和udp編程的主要區別是什麼
tcp和udp從協議上的主要區別是:tcp是可靠的,流時的,但是鏈接建立比較「重」,需要三次握手,udp不能保證數據一定到達接收方,並且數據包並不能保證按照發送方的順序接收。編程上的區別應該並不大,因為底層的api都屏蔽了協議上的差別。
2. c語言 udp socket 簡單客戶端 編程,急
提一下,你那個地址不好用,換成了127.0.0.1,埠可以用,完全按照要求寫的,編譯沒錯誤,調試通過:
gcc server.c -o server
gcc client.c -o client
打開2個控制台:一個運行 ./server 另一個運行 ./client
server.c:
========================================
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#include
#include
#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);
}
3. csocket之udp編程
#include
#include
#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
#include
#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只是進行了封裝而已,原理是一樣的,編程要思路靈活才行。
4. 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、關閉網路連接;
5. 實現udp協議傳輸的c語言程序。如被採納,可追加懸賞,盼高手指教,不勝感激!!!
原型:
int winapi icepub_udpsendandreceive(char *sendbuffer,int bufferlen,char *strip,int port,char *receivebuffer,int timeoutseconds,int retrycounts)
輸入:sendbuffer 發送的數據
bufferlen sendbuffer的長度
strip 服務端地址
port 埠
timeoutseconds 超時時間,秒
retrycounts 接收失敗重發次數
輸出:receivebuffer 接收的數據
返回碼:接收數據的長度
char buff[1024],buff2[1024*10];
int receivelen;
strcpy(buff,"tag:01\r\ncommand:reboot\r\ndata:none\r\n");
typedef int (winapi icepub_udpsendandreceive)(char *sendbuffer,int bufferlen,char *strip,int port,char *receivebuffer,int timeoutseconds,int retrycounts);
icepub_udpsendandreceive *icepub_udpsendandreceive = 0;
hinstance hdlldrv = loadlibrary("icepubdll.dll");
if(hdlldrv)
icepub_udpsendandreceive=(icepub_udpsendandreceive *)getprocaddress(hdlldrv,"icepub_udpsendandreceive");
if(icepub_udpsendandreceive)
receivelen=icepub_udpsendandreceive(buff,strlen(buff),"192.168.1.111",6000,buff2,15,1);
if(hdlldrv)
freelibrary(hdlldrv);
afxmessagebox(buff2);
6. udp編程的時候,一次發送多少bytes好
這個沒有唯一答案,相對於不同的系統,不同的要求,其得到的答案是不一樣的,我這里僅對
像icq一類的發送聊天消息的情況作分析,對於其他情況,你或許也能得到一點幫助:
首先,我們知道,tcp/ip通常被認為是一個四層協議系統,包括鏈路層,網路層,運輸層,應用層.
udp屬於運輸層,下面我們由下至上一步一步來看:
乙太網(ethernet)數據幀的長度必須在46-1500位元組之間,這是由乙太網的物理特性決定的.
這個1500位元組被稱為鏈路層的mtu(最大傳輸單元).
但這並不是指鏈路層的長度被限制在1500位元組,其實這這個mtu指的是鏈路層的數據區.
並不包括鏈路層的首部和尾部的18個位元組.
所以,事實上,這個1500位元組就是網路層ip數據報的長度限制.
因為ip數據報的首部為20位元組,所以ip數據報的數據區長度最大為1480位元組.
而這個1480位元組就是用來放tcp傳來的tcp報文段或udp傳來的udp數據報的.
又因為udp數據報的首部8位元組,所以udp數據報的數據區最大長度為1472位元組.
這個1472位元組就是我們可以使用的位元組數。:)
7. 關於c#中udp編程
//這是一個源碼你看看
using system;
using system.net;
using system.net.sockets;
using system.text;
using system.threading;
using system.windows.forms;
namespace udpclient
{
public partial class frmudp : form
{
private udpclient sendudpclient;
private udpclient receiveupdclient;
public frmudp()
{
initializecomponent();
ipaddress[] ips = dns.gethostaddresses("");
tbxlocalip.text = ips[3].tostring();
int port = 51883;
tbxlocalport.text = port.tostring();
tbxsendtoip.text = ips[3].tostring();
tbxsendtoport.text = port.tostring();
}
// 接受消息
private void btnreceive_click(object sender, eventargs e)
{
// 創建接收套接字
ipaddress localip = ipaddress.parse(tbxlocalip.text);
ipendpoint localipendpoint = new ipendpoint(localip, int.parse(tbxlocalport.text));
receiveupdclient = new udpclient(localipendpoint);
thread receivethread = new thread(receivemessage);
receivethread.start();
}
// 接收消息方法
private void receivemessage()
{
ipendpoint remoteipendpoint = new ipendpoint(ipaddress.any, 0);
while (true)
{
try
{
// 關閉receiveudpclient時此時會產生異常
byte[] receivebytes = receiveupdclient.receive(ref remoteipendpoint);
string message = encoding.unicode.getstring(receivebytes);
// 顯示消息內容
showmessageforview(lstbxmessageview, string.format("{0}[{1}]", remoteipendpoint, message));
}
catch
{
break;
}
}
}
// 利用委託回調機制實現界面上消息內容顯示
delegate void showmessageforviewcallback(listbox listbox, string text);
private void showmessageforview(listbox listbox, string text)
{
if (listbox.invokerequired)
{
showmessageforviewcallback showmessageforviewcallback = showmessageforview;
listbox.invoke(showmessageforviewcallback, new object[] { listbox, text });
}
else
{
lstbxmessageview.items.add(text);
lstbxmessageview.selectedindex = lstbxmessageview.items.count - 1;
lstbxmessageview.clearselected();
}
}
private void btnsend_click(object sender, eventargs e)
{
if (tbxmessagesend.text == string.empty)
{
messagebox.show("發送內容不能為空","提示");
return;
}
// 選擇發送模式
if (chkbxanonymous.checked == true)
{
// 匿名模式(套接字綁定的埠由系統隨機分配)
sendudpclient = new udpclient(0);
}
else
{
// 實名模式(套接字綁定到本地指定的埠)
ipaddress localip = ipaddress.parse(tbxlocalip.text);
ipendpoint localipendpoint = new ipendpoint(localip, int.parse(tbxlocalport.text));
sendudpclient = new udpclient(localipendpoint);
}
thread sendthread = new thread(sendmessage);
sendthread.start(tbxmessagesend.text);
}
// 發送消息方法
private void sendmessage(object obj)
{
string message = (string)obj;
byte[] sendbytes = encoding.unicode.getbytes(message);
ipaddress remoteip = ipaddress.parse(tbxsendtoip.text);
ipendpoint remoteipendpoint = new ipendpoint(remoteip, int.parse(tbxsendtoport.text));
sendudpclient.send(sendbytes, sendbytes.length, remoteipendpoint);
sendudpclient.close();
// 清空發送消息框
resetmessagetext(tbxmessagesend);
}
// 採用了回調機制
// 使用委託實現跨線程界面的操作方式
delegate void resetmessagecallback(textbox textbox);
private void resetmessagetext(textbox textbox)
{
// control.invokerequired屬性代表
// 如果控制項的處理與調用線程在不同線程上創建的,則為true,否則為false
if (textbox.invokerequired)
{
resetmessagecallback resetmessagecallback = resetmessagetext;
textbox.invoke(resetmessagecallback, new object[] { textbox });
}
else
{
textbox.clear();
textbox.focus();
}
}
// 停止接收
private void btnstop_click(object sender, eventargs e)
{
receiveupdclient.close();
}
// 清空接受消息框
private void btnclear_click(object sender, eventargs e)
{
this.lstbxmessageview.items.clear();
}
}
}
8. udp編程中伺服器端運行receivefrom,程序就會像死了一樣如何避免這樣
兩種處理方式:
1.使用非同步,也就是使用 beginreceive/beginreceivefrom以及endreceive/endreceivefrom來接收數據;
2.或啟動一個新的線程,在新的線程中使用receive/receivefrom來執行數據接收。
9. tcp和udp具體編程時的區別
1. socket()的參數不同
udp server不需要調用listen和accept
udp收發數據用sendto/recvfrom函數
tcp:地址信息在connect/accept時確定
udp:在sendto/recvfrom函數中每次均 需指定地址信息
udp:shutdown函數無效
通常我們在說到網路編程時默認是指tcp編程,即用前面提到的socket函數創建一個socket用於tcp通訊,函數參數我們通常填為sock_stream。即socket(pf_inet, sock_stream, 0),這表示建立一個socket用於流式網路通訊。
通過查看socket的man手冊可以看到socket函數的第一個參數的值可以為下面這些值:
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
第二個參數支持下列幾種值:
sock_stream
provides sequenced, reliable, two-way, connection-based byte streams. an out-of-band data transmission mechanism may be sup‐
ported.
sock_dgram
supports datagrams (connectionless, unreliable messages of a fixed maximum length).
sock_seqpacket
provides a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length; a con‐
sumer is required to read an entire packet with each read system call.
sock_raw
provides raw network protocol access.
sock_rdm
provides a reliable datagram layer that does not guarantee ordering.
sock_packet
obsolete and should not be used in new programs; see packet(7).
從這里可以看出,sock_stream這種的特點是面向連接的,即每次收發數據之前必須通過connect建立連接,也是雙向的,即任何一方都可以收發數據,協議本身提供了一些保障機制保證它是可靠的、有序的,即每個包按照發送的順序到達接收方。
而sock_dgram這種是user datagram protocol協議的網路通訊,它是無連接的,不可靠的,因為通訊雙方發送數據後不知道對方是否已經收到數據,是否正常收到數據。任何一方建立一個socket以後就可以用sendto發送數據,也可以用recvfrom接收數據。根本不關心對方是否存在,是否發送了數據。它的特點是通訊速度比較快。大家都知道tcp是要經過三次握手的,而udp沒有。
10. udp和socket通信步驟
這是在網上找到的,希望對你有所幫助。
sockets(套接字)編程有三種,流式套接字(sock_stream),數據報套接字(sock_dgram),原始套接字(sock_raw);
windows環境下tcp/udp編程步驟:
1. 基於tcp的socket編程是採用的流式套接字。
在這個程序中,將兩個工程添加到一個工作區。要鏈接一個ws2_32.lib的庫文件。
伺服器端編程的步驟:
1:載入套接字型檔,創建套接字(wsastartup()/socket());
2:綁定套接字到一個ip地址和一個埠上(bind());
3:將套接字設置為監聽模式等待連接請求(listen());
4:請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept());
5:用返回的套接字和客戶端進行通信(send()/recv());
6:返回,等待另一連接請求;
7:關閉套接字,關閉載入的套接字型檔(closesocket()/wsacleanup())。
伺服器端代碼如下:
#include
#include
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 socksrv=socket(af_inet,sock_stream,0);
sockaddr_in addrsrv;
addrsrv.sin_addr.s_un.s_addr=htonl(inaddr_any);
addrsrv.sin_family=af_inet;
addrsrv.sin_port=htons(6000);
bind(socksrv,(sockaddr*)&addrsrv,sizeof(sockaddr));
listen(socksrv,5);
sockaddr_in addrclient;
int len=sizeof(sockaddr);
while(1)
{
socket sockconn=accept(socksrv,(sockaddr*)&addrclient,&len);
char sendbuf[50];
sprintf(sendbuf,"welcome %s to here!",inet_ntoa(addrclient.sin_addr));
send(sockconn,sendbuf,strlen(sendbuf) 1,0);
char recvbuf[50];
recv(sockconn,recvbuf,50,0);
printf("%s\n",recvbuf);
closesocket(sockconn);
}
}
客戶端編程的步驟:
1:載入套接字型檔,創建套接字(wsastartup()/socket());
2:向伺服器發出連接請求(connect());
3:和伺服器端進行通信(send()/recv());
4:關閉套接字,關閉載入的套接字型檔(closesocket()/wsacleanup())。
客戶端的代碼如下:
#include
#include
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_stream,0);
sockaddr_in addrsrv;
addrsrv.sin_addr.s_un.s_addr=inet_addr("127.0.0.1");
addrsrv.sin_family=af_inet;
addrsrv.sin_port=htons(6000);
connect(sockclient,(sockaddr*)&addrsrv,sizeof(sockaddr));
char recvbuf[50];
recv(sockclient,recvbuf,50,0);
printf("%s\n",recvbuf);
send(sockclient,"hello",strlen("hello") 1,0);
closesocket(sockclient);
wsacleanup();
}
2.基於udp的socket編程是採用的數據報套接字。
在這個程序中,將兩個工程添加到一個工作區。同時還要鏈接一個ws2_32.lib的庫文件。
伺服器端編程的步驟:
1:載入套接字型檔,創建套接字(wsastartup()/socket());
2:綁定套接字到一個ip地址和一個埠上(bind());
3:等待和接收數據(sendto()/recvfrom());
4:關閉套接字,關閉載入的套接字型檔(closesocket()/wsacleanup())。
伺服器端代碼如下:
#include
#include
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 socksrv=socket(af_inet,sock_dgram,0);
sockaddr_in addrsrv;
addrsrv.sin_addr.s_un.s_addr=htonl(inaddr_any);
addrsrv.sin_family=af_inet;
addrsrv.sin_port=htons(7003);
bind(socksrv,(sockaddr*)&addrsrv,sizeof(sockaddr));
char recvbuf[50];
sockaddr addrclient;
int len=sizeof(sockaddr);
recvfrom(socksrv,recvbuf,50,0,(sockaddr*)&addrclient,&len);
printf("%s\n",recvbuf);
closesocket(socksrv);
wsacleanup();
}
對於基於udp的socket客戶端來說,要進行如下步驟:
1:創建一個套接字(socket);
2:向伺服器發送數據(sendto);
3:關閉套接字;
代碼如下:
#include
#include
void main()
{
word wversionrequested;
wsadata wsadata;
int err;
wversionrequested = makeword( 2, 2 );
err = wsastartup( wversionrequested, &wsadata );
if ( err != 0 ) {
return;
}
if ( lobyte( wsadata.wversion ) != 2 ||
hibyte( wsadata.wversion ) != 2 ) {
wsacleanup( );
return;
}
socket sockclient=socket(af_inet,sock_dgram,0);
sockaddr_in addrclient;
addrclient.sin_addr.s_un.s_addr=inet_addr("127.0.0.1");
addrclient.sin_family=af_inet;
addrclient.sin_port=htons(8889);
sockaddr_in addrsrv;
sendto(sockclient,"hi",3,0,(sockaddr*)&addrclient,sizeof(sockaddr));
}
linux環境下tcp/udp編程步驟:
tcp編程步驟:
一. 服務端:
1.socket(int domain,int type,int protocol):建立套接字;
2 .bind(int sockid,struct sockaddr *addrp,socklen_t addrlen):把本機地址和埠跟上一步建立的socket綁定在一起;
3.listen(int sockid,int qsize):監聽某套接字;
4.fd=accept(int sockid,struct sockaddr *callerid,socklen_t *addrlenp):等待某套接字接收信息;
5.recv(int fd,void *buf,size_t nbytes,int flags):從套接字接收數據;
6.close(fd) 和close(sockid)
二.客戶端:
1. socket():建立套接字;
2.connect(int sockid,struct sockaddr *serv_addrp,socklen_t addrlen):連接到伺服器;
3. send(int sockfd,const void *buf,size_t nbytes,int flags):發送數據到伺服器.
4. close(sockid);
udp編程步驟:
一,服務端:
1. socket():同上;
2. bind():同上;
3. recvfrom(int sockfd,void*buff,size_t nbytes,int flags,struct sockaddr*from,socklen_t*addrlen):在套接字口接收數據,並且記錄下接收到的數據來源;一定要注意這里的參數addrlen,它不僅是函數的輸出,也是函數的輸入!所以要在調用該函數之前對addrlen賦值sizeof(struct sockaddr)。否則返回的地址from將會出錯!
4. close(sockfd);
二. 客戶端:
1. socket();同上;
2. sendto(int sockfd,const void*buff,size_t nbytes,int flags,const struct sockaddr*to,socklen_t addrlen):往指定的地址發送數據;
3. close(sockfd);