❶ 怎麼在linux伺服器上測試TCP/UDP埠的連通性
翻譯自:
How to Test Port[TCP/UDP] Connectivity from a Linux Server (文檔 ID 2212626.1)
適用於:
Linux OS - Version Oracle Linux 5.0 to Oracle Linux 6.8 [Release OL5 to OL6U8]
Information in this document applies to any platform.
目標:
在Linux伺服器上檢查TCP/UDP埠的連通性。
解決方案:
telnet和nc 是用來測試埠連通性的一般工具。
telnet可以測試tcp埠的連通性。
nc可以測試tcp和udp埠的連通性。
請確保telnet和nc工具已經安裝
在CODE上查看代碼片派生到我的代碼片
# yum install nc
# yum install telnet
測試tcp埠的連通性:
語法如下:
在CODE上查看代碼片派生到我的代碼片
telnet <hostname/IP address> <port number>
如下是連通成功的例子:
在CODE上查看代碼片派生到我的代碼片
# telnet 192.118.20.95 22
Trying 192.118.20.95...
Connected to 192.118.20.95.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1
Protocol mismatch.
Connection closed by foreign host.
如下是連通不成功的例子:
在CODE上查看代碼片派生到我的代碼片
# telnet 192.118.20.95 22
Trying 192.118.20.95...
telnet: connect to address 192.118.20.95: No route to host
使用nc命令來測試tcp埠的連通性:
語法:
在CODE上查看代碼片派生到我的代碼片
nc -z -v <hostname/IP address> <port number>
如下是連通成功的例子:
在CODE上查看代碼片派生到我的代碼片
# nc -z -v 192.118.20.95 22
Connection to 192.118.20.95 22 port [tcp/ssh] succeeded!
如下是連通不成功的例子:
在CODE上查看代碼片派生到我的代碼片
# nc -z -v 192.118.20.95 22
nc: connect to 192.118.20.95 port 22 (tcp) failed: No route to host
使用nc命令來測試udp埠的連通性:
語法:
在CODE上查看代碼片派生到我的代碼片
nc -z -v -u <hostname/IP address> <port number>
在CODE上查看代碼片派生到我的代碼片
# nc -z -v -u 192.118.20.95 123
Connection to 192.118.20.95 123 port [udp/ntp] succeeded!
nc檢測埠的用法
nc -z -w 10 %IP% %PORT%
-z表示檢測或者掃描埠
-w表示超時時間
-u表示使用UDP協議
❷ Linux系統如何阻擋UDP攻擊
UDP Server程序
1、編寫UDP Server程序的步驟
(1)使用socket()來建立一個UDP socket,第二個參數為SOCK_DGRAM。
(2)初始化sockaddr_in結構的變數,並賦值。sockaddr_in結構定義:
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
這里使用「08」作為服務程序的埠,使用「INADDR_ANY」作為綁定的IP地址即任何主機上的地址。
(3)使用bind()把上面的socket和定義的IP地址和埠綁定。這里檢查bind()是否執行成功,如果有錯誤就退出。這樣可以防止服務程序重復運行的問題。
(4)進入無限循環程序,使用recvfrom()進入等待狀態,直到接收到客戶程序發送的數據,就處理收到的數據,並向客戶程序發送反饋。這里是直接把收到的數據發回給客戶程序。
2、udpserv.c程序內容:
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 80
#define SERV_PORT 8888
void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE];
for(;;)
{
len = clilen;
/* waiting for receive data */
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
/* sent data back to client */
sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
/* bind address and port to socket */
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
perror("bind error");
exit(1);
}
do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
return 0;
}
UDP Client程序
1、編寫UDP Client程序的步驟
(1)初始化sockaddr_in結構的變數,並賦值。這里使用「8888」作為連接的服務程序的埠,從命令行參數讀取IP地址,並且判斷IP地址是否符合要求。
(2)使用socket()來建立一個UDP socket,第二個參數為SOCK_DGRAM。
(3)使用connect()來建立與服務程序的連接。與TCP協議不同,UDP的connect()並沒有與服務程序三次握手。上面我們說了UDP是非連接的,實際上也可以是連接的。使用連接的UDP,kernel可以直接返回錯誤信息給用戶程序,從而避免由於沒有接收到數據而導致調用recvfrom()一直等待下去,看上去好像客戶程序沒有反應一樣。
(4)向服務程序發送數據,因為使用連接的UDP,所以使用write()來替代sendto()。這里的數據直接從標准輸入讀取用戶輸入。
(5)接收服務程序發回的數據,同樣使用read()來替代recvfrom()。
(6)處理接收到的數據,這里是直接輸出到標准輸出上。
2、udpclient.c程序內容:
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAXLINE 80
#define SERV_PORT 8888
void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
/* connect to server */
if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
{
perror("connect error");
exit(1);
}
while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
write(sockfd, sendline, strlen(sendline));
/* receive data from server */
n = read(sockfd, recvline, MAXLINE);
if(n == -1)
{
perror("read error");
exit(1);
}
recvline[n] = 0; /* terminate string */
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in srvaddr;
/* check args */
if(argc != 2)
{
printf("usage: udpclient <IPaddress>\n");
exit(1);
}
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
printf("[%s] is not a valid IPaddress\n", argv[1]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
return 0;
}
運行例子程序
1、編譯例子程序
使用如下命令來編譯例子程序:
gcc -Wall -o udpserv udpserv.c
gcc -Wall -o udpclient udpclient.c
編譯完成生成了udpserv和udpclient兩個可執行程序。
2、運行UDP Server程序
執行./udpserv &命令來啟動服務程序。我們可以使用netstat -ln命令來觀察服務程序綁定的IP地址和埠,部分輸出信息如下:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
udp 0 0 0.0.0.0:32768 0.0.0.0:*
udp 0 0 0.0.0.0:8888 0.0.0.0:*
udp 0 0 0.0.0.0:111 0.0.0.0:*
udp 0 0 0.0.0.0:882 0.0.0.0:*
可以看到udp處有「0.0.0.0:8888」的內容,說明服務程序已經正常運行,可以接收主機上任何IP地址且埠為8888的數據。
如果這時再執行./udpserv &命令,就會看到如下信息:
bind error: Address already in use
說明已經有一個服務程序在運行了。
3、運行UDP Client程序
執行./udpclient 127.0.0.1命令來啟動客戶程序,使用127.0.0.1來連接服務程序,執行效果如下:
Hello, World!
Hello, World!
this is a test
this is a test
^d
輸入的數據都正確從服務程序返回了,按ctrl+d可以結束輸入,退出程序。
如果服務程序沒有啟動,而執行客戶程序,就會看到如下信息:
$ ./udpclient 127.0.0.1
test
read error: Connection refused
說明指定的IP地址和埠沒有服務程序綁定,客戶程序就退出了。這就是使用connect()的好處,注意,這里錯誤信息是在向服務程序發送數據後收到的,而不是在調用connect()時。如果你使用tcpmp程序來抓包,會發現收到的是ICMP的錯誤信息。
參考資料:http://www.cnpaf.net/Class/UDP/0532918532729212.html
❸ 檢測基於udp的服務端,在windows下,和linux各用什麼命令
兩個系統都是用netstat命令,選項不一樣而已
linux中查看udp連接,netstat -u
windows中:netstat -p udp
❹ windows下的udp協議如何與linux下的udp協議連接,傳送數據
udp和操作系統沒有關系。
至於埠怎麼打開,數據怎麼發送和接受,和對數據進行怎麼樣的處理,是你雙端自己所寫程序決定的。
❺ linux下udp實現文件的傳輸,盡量詳細點 思路我知道 就是不知道怎麼把文件名給傳過去
傳文件最好用個TCP。UDP會丟包的
////////////////////////////////////
//客戶端代碼
///////////////////////////////////
//本文件是客戶機的代碼
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <time.h> //for time_t and time
#include <arpa/inet.h>
#define HELLO_WORLD_SERVER_PORT 7754
#define BUFFER_SIZE 1024
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("Usage: ./%s ServerIPAddress\n",argv[0]);
exit(1);
}
//time_t now;
FILE *stream;
//設置一個socket地址結構client_addr,代表客戶機internet地址, 埠
struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(client_addr)); //把一段內存區的內容全部設置為0
client_addr.sin_family = AF_INET; //internet協議族
client_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自動獲取本機地址
client_addr.sin_port = htons(0); //0表示讓系統自動分配一個空閑埠
//創建用於internet的流協議(TCP)socket,用client_socket代表客戶機socket
int client_socket = socket(AF_INET,SOCK_STREAM,0);
if( client_socket < 0)
{
printf("Create Socket Failed!\n");
exit(1);
}
//把客戶機的socket和客戶機的socket地址結構聯系起來
if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
{
printf("Client Bind Port Failed!\n");
exit(1);
}
//設置一個socket地址結構server_addr,代表伺服器的internet地址, 埠
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(inet_aton(argv[1],&server_addr.sin_addr) == 0) //伺服器的IP地址來自程序的參數
{
printf("Server IP Address Error!\n");
exit(1);
}
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
//向伺服器發起連接,連接成功後client_socket代表了客戶機和伺服器的一個socket連接
if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
{
printf("Can Not Connect To %s!\n",argv[1]);
exit(1);
}
char buffer[BUFFER_SIZE];
bzero(buffer,BUFFER_SIZE);
//從伺服器接收數據到buffer中
int length = recv(client_socket,buffer,BUFFER_SIZE,0);
if(length < 0)
{
printf("Recieve Data From Server %s Failed!\n", argv[1]);
exit(1);
}
printf("\n%s\n",buffer);
bzero(buffer,BUFFER_SIZE);
bzero(buffer,BUFFER_SIZE);
strcpy(buffer,"Hello, World! From Client\n");
//向伺服器發送buffer中的數據
send(client_socket,buffer,BUFFER_SIZE,0);
if((stream = fopen("data","w+t"))==NULL)
{
printf("The file 'data' was not opened! \n");
}
else
bzero(buffer,BUFFER_SIZE);
length = 0;
while( length = recv(client_socket,buffer,BUFFER_SIZE,0))
{
if(length < 0)
{
printf("Recieve Data From Server %s Failed!\n", argv[1]);
break;
}
int write_length = fwrite(buffer,sizeof(char),length,stream);
if (write_length<length)
{
printf("File is Write Failed\n");
break;
}
bzero(buffer,BUFFER_SIZE);
}
printf("Recieve File From Server[%s] Finished\n", argv[1]);
//關閉 文件
fclose(stream);
//關閉socket
close(client_socket);
return 0;
}
////////////////////////////////////
//伺服器代碼
///////////////////////////////////
//本文件是伺服器的代碼
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
#include <time.h> //for time_t and time
#define HELLO_WORLD_SERVER_PORT 7754
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
int main(int argc, char **argv)
{
//設置一個socket地址結構server_addr,代表伺服器internet地址, 埠
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr)); //把一段內存區的內容全部設置為0
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
// time_t now;
FILE *stream;
//創建用於internet的流協議(TCP)socket,用server_socket代表伺服器socket
int server_socket = socket(AF_INET,SOCK_STREAM,0);
if( server_socket < 0)
{
printf("Create Socket Failed!");
exit(1);
}
//把socket和socket地址結構聯系起來
if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
{
printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
exit(1);
}
//server_socket用於監聽
if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) )
{
printf("Server Listen Failed!");
exit(1);
}
while (1) //伺服器端要一直運行
{
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);
if ( new_server_socket < 0)
{
printf("Server Accept Failed!\n");
break;
}
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strcpy(buffer,"Hello,World! 從伺服器來!");
strcat(buffer,"\n"); //C語言字元串連接
send(new_server_socket,buffer,BUFFER_SIZE,0);
bzero(buffer,BUFFER_SIZE);
//接收客戶端發送來的信息到buffer中
length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
if (length < 0)
{
printf("Server Recieve Data Failed!\n");
exit(1);
}
printf("\n%s",buffer);
if((stream = fopen("/home/administrator/110405A000.jpg","r"))==NULL)
{
printf("The file 'data1' was not opened! \n");
exit(1);
}
else
printf("The file 'filename' was opened! \n");
bzero(buffer,BUFFER_SIZE);
int lengsize = 0;
while((lengsize = fread(buffer,1,1024,stream)) > 0)
{
printf("lengsize = %d\n",lengsize);
if(send(new_server_socket,buffer,lengsize,0)<0)
{
printf("Send File is Failed\n");
break;
}
bzero(buffer, BUFFER_SIZE);
}
if(fclose(stream))
printf("The file 'data' was not closed! \n");
exit(1);
//關閉與客戶端的連接
close(new_server_socket);
}
//關閉監聽用的socket
close(server_socket);
return 0;
}
❻ 如何在單機Linux上運行Socket TCP和UDP Server/Client的通信程序
最好先安裝windows XP pro系統再安抄裝Linux,安裝很簡單的,和軟體一樣。
如果你想學LINUX,那可得下一翻功夫,學習方向很多的,比如伺服器配置,編程,源碼分析,可以說LINUx是中國的系統軟體,包括嵌入式系統,開發自己的系統,在計算機領域打出一片自己的天下的很好的契機。
❼ linux socket網路編程 UDP(server)程序設計 求大神解惑 有個地方搞不定了
將fprintf(stderr那行改成herror("can not get something");
然後再試試
另外,你確定你的if語句後面應該跟著個分號嗎 - -,你跟了分號表版示該語句結束
那麼自權然的後面的語句塊中的內容就被執行了
❽ 求指點,linux下c++,udp server端,詳細如下。
上面的代碼中綁定了之後再建一個線程接受就行了。思路大概是這樣:
int main
{
。。。。。。// ....和你前面寫的一樣
bind(...); // 就像你寫的那樣。
pthead_t pid;
pthread_create( &pid, NULL, do_receive, &udpsock ); //建線程,但參數的傳遞不一定對,你可以查一查pthread_create函數。
pthread_join( pid, NULL );
close(udpsock);
return 0;
}
// 線程體
void* do_receive( void* udpsock_ptr )
{
int udpsock = *(int*)udpsock_ptr;
struct sockaddr_in client;
int length=sizeof(struct sockaddr_in);
char msg[100]
while ( 1 )
{
recvfrom( udpsock, msg, sizeof( msg ), ,(struct sockaddr*)&client,(socklen_t*)&length);
// 接下來就是判斷接受的是1或2了。。這你自己做。
}
return (void*)NULL;
}
❾ windows 下 或 linux 可以用什麼命令 模擬udp客戶端 ,往udp服務端發送數據,
telnet服務就是使用udp協議的,或者到網上下載udp客戶端軟體
❿ 使用recvfrom接收UDP包在Windows和Linux平台的不同表現
1 UDP接收原理
操作系統的UDP接收流程如下:收到一個UDP包後,驗證沒有錯誤後,放入一個包隊列中,隊列中的每一個元素就是一個完整的UDP包。當應用程序通過recvfrom()讀取時,OS把相應的一個完整UDP包取出,然後拷貝到用戶提供的內存中,物理用戶提供的內存大小是多少,OS都會完整取出一個UDP包。如果用戶提供的內存小於這個UDP包的大小,那麼在填充慢內存後,UDP包剩餘的部分就會被丟棄,以後再也無法取回。
這與TCP接收完全不同,TCP沒有完整包的概念,也沒有邊界,OS只會取出用戶要求的大小,剩餘的仍然保留在OS中,下次還可以繼續取出。
socket編程雖然是事實上的標准,而且不同平台提供的介面函數也非常類似,但畢竟它不存在嚴格的標准。所以各個平台的實現也不完全兼容。下面就從recvfrom()這個函數看看Window平台和Linux平台的不同。
2 Windows平台的表現
先看頭文件中的聲明:
[cpp] view plain在CODE上查看代碼片派生到我的代碼片
int
WSAAPI
recvfrom(
_In_ SOCKET s,
_Out_writes_bytes_to_(len, return) __out_data_source(NETWORK) char FAR * buf,
_In_ int len,
_In_ int flags,
_Out_writes_bytes_to_opt_(*fromlen, *fromlen) struct sockaddr FAR * from,
_Inout_opt_ int FAR * fromlen
);
再看MSDN說明:
If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recvfrom generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost.
可以看出,buf大小小於UDP包大小的時候,recvfrom()會返回-1,並設置錯誤WSAEMSGSIZE。
實際編程測試驗證確實是這樣的表現。
3 Linux平台的表現
先看頭文件中的聲明:
[cpp] view plain在CODE上查看代碼片派生到我的代碼片
__extern_always_inline ssize_t
recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,
__SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
可以看出與Windows平台的函數原型相同。但是在其man手冊里,沒有看到UDP包大於接收緩沖區情況的特殊說明。
寫代碼測試表明,buf小於UDP包大小的時候,recvfrom()仍然返回復制到緩沖區的位元組數,調用者無法得知UDP包被截斷的情況。
4 寫代碼注意事項
UDP包最大是多大呢?UDP頭部大小欄位佔16位元組,所以理論上是65535個位元組大小。但是UDP如果是通過IP(大多數情況)來傳送,由於UDP本身不支持分片,所以一個UDP包只能通過一個IP包來傳送,一個IP包大大小理論上也是用16位元組表示,這樣UDP最大大小就是(65535-IP頭部)。
而現實中如果IP包大小大於底層鏈路層幀的最大數據區大小,則必須對IP包進行分片傳送。分片會嚴重影響傳送效率,而且增大不穩定性,所以實際的網路程序發送的IP包都封裝到單一的鏈路層幀中,從而避免分片。問題是鏈路層幀是多大呢?答案是不一定,因為不同的物理網路的幀大小不一樣,如乙太網是1500位元組,但是其他物理網路可能更小,Internet上的有個最小的限制,那就是576位元組。如果UDP程序運行在只運行在乙太網中,那麼為了避免IP分片,可以採用的最大大小為(1500-20-8)=1472位元組。如果UDP程序需要運行在Internet上,那麼建議最大大小為(576-20-8)=548位元組。
上面是實踐中的最佳UDP大小,但是並不是所有程序都採用上述經驗,所以對於接收緩沖區的大小也就沒有一個標准,而是取決於應用程序設計者本身。雖然對於Windows平台,recvfrom()能夠提示調用者buf過小的問題,但是即使得到了這個錯誤,包還是被丟棄了。所以在接收UDP包時,一定要事先了解應用層設計的最大UDP包大小,然後按照最大值開辟接收緩沖區。