Windows下的UDP?
Windows下的用VC++6.0這個軟體編寫的UDP協議的socket程式設計
工具/原料
膝上型電腦一臺
安裝了VC++6.0
方法/步驟
首先在電腦上安裝好VC++6.0。這個網上已經有很多教程了,本文就不多做介紹了。
瞭解一下網路知識,TCP,UDP以及SOCKET是什麼。其實socket就是一個五元組,網路協議,本地埠,本地IP,遠地埠,遠地IP。socket程式設計主要是把資料傳送到一個本地的緩衝區,而從本地傳輸到遠地的計算機這個過程則無需我們管。
接著,你要了解一下socket函式庫裡的一些函式和結構體。隨便找一本網路程式設計的書,裡面基本都有關於socket庫的介紹,描述。下面舉幾個本文程式設計會用到的
int sendto ( socket s , const void * msg, int len, unsigned int flags, const
struct sockaddr * to , int tolen ) ; //傳送
int recvfrom(int sockfd,void *buf,int len,unsigned int flags, struct sockaddr *from,socket_t *fromlen); //接收
SOCKET socket( int af, int type, int protocol); //初始化SOCKET
closesocket(); //關閉SOCKET
最後貼出程式,其實程式很簡單,懂了網路協議,以及SOCKET,基本都能看懂這個程式,如果有哪些函式不懂,可以百度一下。
client.cpp
#include
#include
#include
using namespace std;
#pragma comment(lib, "ws2_32.lib ")
bool Socketbind(SOCKET& socket,short port ,const char* Ip);
int main()
{
WORD wVersionRequested;
WSADATA wData; // 這結構是用於接收Wjndows Socket的結構資訊的
int err;
int port,Otherport;
char IPaddr[18];
char OtherIP[18];
wVersionRequested = MAKEWORD( 1, 1 ); // 請求WinSock庫
err = WSAStartup( wVersionRequested, &wData );
if ( err != 0 ) {
return -1; // 返回值為零時表示成功WSAStartup
}
SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
if(sockCli<0)
{
printf("failed");
return 0;
}
printf("NEWSocket success.\n");
printf("請輸入本機IP地址:\n");
gets(IPaddr);
printf("請輸入本機埠號:\n");
scanf("%d",&port);
if(! BindSocket(sockCli,port,IPaddr) )
{
printf("failed");
return 0;
}
printf("BindSocket success.\n");
SOCKADDR_IN address;
printf("請輸入遠機IP地址:\n");
scanf("%s",OtherIP);
printf("請輸入遠機埠號:\n");
scanf("%d",&Otherport);
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(OtherIP);
address.sin_port=htons(Otherport);
char talk[100]={0};
gets(talk);
SOCKADDR_IN addre;
int n=sizeof(struct sockaddr);
char buffer[100] = "ghfd";
while(talk[0]!='f')
{
printf("please talk:\n");
gets(talk);
if( sendto(sockCli,talk, sizeof(talk), 0,(const struct sockaddr*)&address,sizeof(struct sockaddr) ) ==SOCKET_ERROR )
printf("傳送失敗\n");
recvfrom(sockCli,buffer,100,0,(struct sockaddr*)&addre,&n);
puts(buffer);
}
closesocket(sockCli);
WSACleanup();
}
bool Socketbind(SOCKET& socket,short port ,const char* Ip)
{
SOCKADDR_IN address;
address.sin_family=AF_INET;
address.sin_addr.s_addr =inet_addr(Ip);
address.sin_port=htons(port);
if(SOCKET_ERROR == bind(socket,(const struct sockaddr*)&address,sizeof(struct sockaddr)) )
{
return false;
}
return true;
}
server.cpp
#include
#include
using namespace std;
#pragma comment(lib, "ws2_32.lib ")
bool BindSocket(SOCKET& socket,short port ,const char* sIp);
int main()
{
WORD wVersionRequested;
WSADATA wData; // 這結構是用於接收Wjndows Socket的結構資訊的
int err;
int port;
char IPaddr[18];
SOCKADDR_IN address;
int n=sizeof(struct sockaddr);
char talk[100]={0};
char buffer[100] = {0};
wVersionRequested = MAKEWORD( 1, 1 ); // 請求WinSock庫
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return -1; // 返回值為零時表示成功WSAStartup
}
SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
if(sockSrv<0)
{
printf("failed");
return 0;
}
printf("NEWSocket success.\n");
printf("請輸入本機IP地址:\n");
gets(IPaddr);
printf("請輸入本機埠號:\n");
scanf("%d",&port);
gets(buffer); //去掉回車
while(! BindSocket(sockSrv,port,IPaddr) )
{
printf("failed");
printf("請輸入本機埠號:\n");
scanf("%d",&port);
}
printf("BindSocket success.\n");
while(buffer[0]!='f')
{
if(recvfrom(sockSrv,buffer, 100,0,(struct sockaddr*)&address,&n) ==SOCKET_ERROR )
printf("接收失敗\n");
else
{
puts(buffer);
printf("please talk:\n");
gets(talk);
sendto(sockSrv,talk, sizeof(talk), 0,(const struct sockaddr*)&address,sizeof(struct sockaddr) );
}
}
closesocket(sockSrv);
WSACleanup();
}
bool Socketbind(SOCKET& socket,short port ,const char* Ip)
{
SOCKADDR_IN address;
address.sin_family=AF_INET;
address.sin_addr.s_addr =inet_addr(Ip);
address.sin_port=htons(port);
memset(address.sin_zero,0,sizeof(address.sin_zero));
if(SOCKET_ERROR == bind(socket,(const struct sockaddr*)&address,sizeof(struct sockaddr)) )
{
return false;
}
return true;
}
注意事項
在區域網下可以正常進行通訊,跨區域網則需要進行路由器的埠對映。