UDP和Socket通信步骤

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UDP和Socket通信步骤相关的知识,希望对你有一定的参考价值。

参考技术A 这是在网上找到的,希望对你有所帮助。
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 <stdio.h>

#include <Winsock2.h>

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 <stdio.h>

#include <Winsock2.h>

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 <winsock2.h>

#include <stdio.h>

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 <winsock2.h>

#include <stdio.h>

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);

参考资料:http://blogold.chinaunix.net/u3/94667/showart_2379087.html

来自:求助得到的回答
参考技术A 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()时。如果你使用tcpdump程序来抓包,会发现收到的是ICMP的错误信息。本回答被提问者和网友采纳

C++基于TCP和UDP的socket通信

TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它事先为要发送的数据开辟好连接通道(三次握手),然后再进行数据发送;而UDP则不为IP提供可靠性,一般用于实时的视频流传输,像rtp、rtsp就是建立在udp的基础上的。

     首先谈谈tcp socket

技术分享

    tcp简单的三次握手过程如图,

    SYN(Synchronize Sequence Numbers):同步标志  

    ACK(Acknowledgement Number)        :确认标志

    图中可以看出,三次握手的过程是在c的connect()和s的bind()、listen()、accept()函数中完成的,这样开辟了相对可靠的连接通道,来传输数据。

UDP的socket编程过程如下图所示:

技术分享

下面翠花上代码啦!技术分享

服务端:

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <Winsock2.h> //windows socket的头文件  
  3.   
  4. #pragma comment( lib, "ws2_32.lib" )// 链接Winsock2.h的静态库文件  
  5.   
  6. void main()  
  7. {  
  8.     //初始化winsocket  
  9.     WORD wVersionRequested;  
  10.     WSADATA wsaData;  
  11.     int err;  
  12.   
  13.     wVersionRequested = MAKEWORD( 1, 1 );//第一个参数为低位字节;第二个参数为高位字节  
  14.   
  15.     err = WSAStartup( wVersionRequested, &wsaData );//对winsock DLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。  
  16.     if ( err != 0 )  
  17.     {  
  18.         return;  
  19.     }  
  20.   
  21.     if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )//LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容        
  22.     {  
  23.         WSACleanup( );  
  24.         return;  
  25.     }  
  26.   
  27.     SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建socket。AF_INET表示在Internet中通信;SOCK_STREAM表示socket是流套接字,对应tcp;0指定网络协议为TCP/IP  
  28.   
  29.     SOCKADDR_IN addrSrv;   
  30.     addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //htonl用来将主机字节顺序转换为网络字节顺序(to network long)  
  31.     //INADDR_ANY就是指定地址为0.0.0.0的地址,  
  32.     //表示不确定地址,或“任意地址”。”  
  33.     addrSrv.sin_family=AF_INET;   
  34.     addrSrv.sin_port=htons(4000);//htons用来将主机字节顺序转换为网络字节顺序(to network short)  
  35.   
  36.     bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//将本地地址绑定到所创建的socket上,以使在网络上标识该socket  
  37.   
  38.     listen(sockSrv,5);//socket监听,准备接受连接请求。  
  39.   
  40.     SOCKADDR_IN addrClient;  
  41.     int len=sizeof(SOCKADDR);  
  42.   
  43.     while(1)  
  44.     {  
  45.         SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//为一个连接请求提供服务。addrClient包含了发出连接请求的客户机IP地址信息;返回的新socket描述服务器与该客户机的连接  
  46.   
  47.         char sendBuf[50];  
  48.         sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));//inet_ntoa网络地址转换转点分十进制的字符串指针  
  49.         send(sockConn,sendBuf,strlen(sendBuf)+1,0);  
  50.   
  51.         char recvBuf[50];  
  52.         recv(sockConn,recvBuf,50,0);  
  53.         printf("%s\n",recvBuf);  
  54.   
  55.         closesocket(sockConn);  
  56.         Sleep(2000);//2000毫秒  
  57.     }  
  58.     WSACleanup();  
  59. }  

 

客户端:

 

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <Winsock2.h>  
  3.   
  4. #pragma comment( lib, "ws2_32.lib" )   
  5.   
  6.   
  7. void main()  
  8. {  
  9.     WORD wVersionRequested;  
  10.     WSADATA wsaData;  
  11.     int err;  
  12.   
  13.     wVersionRequested = MAKEWORD( 1, 1 );//第一个参数为低位字节;第二个参数为高位字节  
  14.   
  15.     err = WSAStartup( wVersionRequested, &wsaData );//对winsock DLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。  
  16.     if ( err != 0 )  
  17.     {  
  18.         return;  
  19.     }  
  20.   
  21.     if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )//LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容        
  22.     {  
  23.         WSACleanup( );  
  24.         return;  
  25.     }  
  26.     for(int index=0;;index++)  
  27.     {  
  28.         SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);  
  29.   
  30.         SOCKADDR_IN addrClt;//需要包含服务端IP信息  
  31.         addrClt.sin_addr.S_un.S_addr=inet_addr("192.168.0.30");// inet_addr将IP地址从点数格式转换成网络字节格式整型。  
  32.         addrClt.sin_family=AF_INET;   
  33.         addrClt.sin_port=htons(4000);  
  34.   
  35.         connect(sockClient,(SOCKADDR*)&addrClt,sizeof(SOCKADDR));//客户机向服务器发出连接请求  
  36.         char recvBuf[50];  
  37.         recv(sockClient,recvBuf,50,0);  
  38.         printf("my reply is : %s\n",recvBuf);  
  39.   
  40.         char sendBuf[50];  
  41.         sprintf(sendBuf,"%3d,",index);  
  42.         strcat(sendBuf,"server node of: yaopeng");  
  43.         send(sockClient,sendBuf,strlen(sendBuf)+1,0);  
  44.   
  45.         closesocket(sockClient);  
  46.         Sleep(2000);  
  47.     }  
  48.     WSACleanup();  
  49. }  



 

对于tcp socket,有几点需要注意:

一、TCP的TIME_WAIT状态(等待客户端的相应)    

注*  TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟(MSL是最大分段生存期,指明TCP报文在Internet上最长生存时间)

    当服务器端socket绑定本地地址并占用了端口,此时如果匆忙结束;或者连接的服务器异常退出,这个时候被占用的端口不能马上释放,需要TIME_WAIT。即便调用closesocket()一般也不会立即关闭socket,仍可继续重用该socket。所以重新启动服务器时可能会出现问题。例如MFC中在子窗口中实现socket通信,那么关闭子窗口再打开就会出问题了。

     解决方法是在bind()之前添加setsockopt()函数,解除端口绑定。

介绍setsockopt()之前我们再来回顾一下三次握手协议的具体流程:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 

完成三次握手,客户端与服务器开始传送数据。

setsockopt()使用方法如下:

    1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));

    2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:
BOOL  bDontLinger = FALSE; 
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));

更多setsockopt()函数用例可参考百度百科:http://baike.baidu.com/view/569217.htm

 

 二、对于大型文件,一般需要将其剁碎了一部分一部分的传。TCP不能保证接收方顺序的收到包,对于需要实时显示的文件可以在发送方发出包后设置来自接收方的响应,即对方收到前一个包后再发送下一个包。

目前就这么多,各位看官有其他的注意事项拜托请留言补充,小弟感激啊。

 

下面简单说下UDP socket

    UDP不能保证双方的可靠连接,容易出现丢包现象。

    UDP的socket编程过程如下图所示:

技术分享

 

上代码了,哈哈。

服务端:

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <Winsock2.h>  
  3.   
  4. #pragma comment( lib, "ws2_32.lib" )   
  5.    
  6. void main()  
  7. {  
  8.     WORD wVersionRequested;  
  9.     WSADATA wsaData;  
  10.     int err;  
  11.   
  12.     wVersionRequested = MAKEWORD( 1, 1 );   
  13.   
  14.     err = WSAStartup( wVersionRequested, &wsaData );   
  15.     if ( err != 0 ) {  
  16.         return;  
  17.     }  
  18.   
  19.     if ( LOBYTE( wsaData.wVersion ) != 1 ||  
  20.         HIBYTE( wsaData.wVersion ) != 1 ) {   
  21.             WSACleanup( );  
  22.             return;  
  23.     }  
  24.     SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);  
  25.       
  26.     int len=sizeof(SOCKADDR);  
  27.       
  28.     SOCKADDR_IN from;     
  29.     SOCKADDR_IN local;   
  30.     local.sin_addr.S_un.S_addr=htonl(INADDR_ANY);   
  31.     local.sin_family=AF_INET;   
  32.     local.sin_port=htons(27015);   
  33.   
  34.     int a = bind(sockSrv,(SOCKADDR*)&local,len);  
  35.    
  36.       
  37.   
  38.     while(1)  
  39.     {  
  40.         char recvBuf[50];  
  41.         recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&from,&len);//from收到客户端的IP信息  
  42.         printf("%s\n",recvBuf);  
  43.         printf("%s\n",inet_ntoa(local.sin_addr));  
  44.         char sendBuf[50];  
  45.         sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(from.sin_addr));    
  46.         sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&from,len);  
  47.           
  48.         Sleep(2000);  
  49.     }  
  50.     closesocket(sockSrv);  
  51.     WSACleanup();  
  52. }  


客户端:

[cpp] view plain copy
 
  1. #include <stdio.h>  
  2. #include <Winsock2.h>  
  3.   
  4. #pragma comment( lib, "ws2_32.lib" )   
  5.   
  6.   
  7. void main()  
  8. {  
  9.     WORD wVersionRequested;  
  10.     WSADATA wsaData;  
  11.     int err;  
  12.   
  13.     wVersionRequested = MAKEWORD( 1, 1 );   
  14.   
  15.     err = WSAStartup( wVersionRequested, &wsaData );   
  16.     if ( err != 0 ) {  
  17.         return;  
  18.     }  
  19.   
  20.     if ( LOBYTE( wsaData.wVersion ) != 1 ||  
  21.         HIBYTE( wsaData.wVersion ) != 1 ) {   
  22.             WSACleanup( );  
  23.             return;  
  24.     }  
  25.       
  26.   
  27.     for(int index=0;;index++)  
  28.     {  
  29.         SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);  
  30.   
  31.         int len = sizeof(SOCKADDR);  
  32.   
  33.         SOCKADDR_IN local;  
  34.         local.sin_addr.S_un.S_addr=inet_addr("192.168.0.30");   
  35.         local.sin_family=AF_INET;   
  36.         local.sin_port=htons(27015);   
  37.    
  38.         char sendBuf[30];  
  39.         sprintf(sendBuf,"%3d,",index);  
  40.         strcat(sendBuf,"server node of: yaopeng");  
  41.         sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&local,len);  
  42.   
  43.         char recvBuf[50];  
  44.         recvfrom(sockClient,recvBuf,50,0,(SOCKADDR*)&local,&len);  
  45.         printf("my reply is : %s\n",recvBuf);  
  46.         printf("%s\n",inet_ntoa(local.sin_addr));  
  47.   
  48.         closesocket(sockClient);  
  49.         Sleep(2000);  
  50.         WSACleanup();  
  51.     }  
  52. }  

 
   完了。关于socket编程还有很多函数没有涉及,急待跟进完善。欢迎大家给我留言!技术分享

以上是关于UDP和Socket通信步骤的主要内容,如果未能解决你的问题,请参考以下文章

Java系列讲座二:Socket网络通信实现聊天软件项目讲解(UDP)

Java系列讲座二:Socket网络通信实现聊天软件项目讲解(UDP)

UDP----socket通信

Linux(程序设计):42---UDP网络编程(单播)

计算机网络——Socket实验2

计算机网络——Socket实验2