最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

基于TCP和UDP的Socket编程

来源:动视网 责编:小OO 时间:2025-09-28 20:52:37
文档

基于TCP和UDP的Socket编程

基于TCP和UDP的Socket编程在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息UDP:是无连接的在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手
推荐度:
导读基于TCP和UDP的Socket编程在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息UDP:是无连接的在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手
基于TCP和UDP的Socket编程 

在OSI的各层所使用的协议: 1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP3 2.传输层:TCP,UDP TCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息 UDP:是无连接的

在OSI的各层所使用的协议: 

1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP3 

2.传输层:TCP,UDP 

TCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息 

UDP:是无连接的,不可靠的传输协议,不需要建立连接,也没有重传和确认的机制,在实时性要求较高,但对数据准确度要求不是很高的场合使用,如视频会议,在线观看电影,当中丢失个别数据包并不影响整体的效果。 

3.网络层:IP 

因为OSI七层结构较为复杂,所以使用较多的是TCP/IP模型,现在TCP/IP已经成为Internet上通用的工业标准 

TCP/IP模型包括4个层次:应用层,传输层,网络层,网络接口 

端口: 

1. 为了标识通信实体中进行通信的进程(应用程序),TCP/IP协议提出了协议端口的概念 

2. 端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序通过系统调用和某端口建立连接(binding)后,传输层传给该端口的数据都被相应的进程所接收,相应进程发给传输层的数据都通过该端口输出 

3. 端口用一个整数型标识符来表示,即端口号。端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全的的两个软件模块,因此各自的端口号也相互 

4. 端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务,例如,http使用80端口 

套接字(Socket) 

1. Socket的出现,使得程序员可以很方便的访问TCP/IP,从而开发各种网络应用的程序 

2. 套接字存在于通信区域中,通信区域也叫地址族,他是一个抽象的概念,主要用于通过套接字通信的进程的共有特性综合在一起。套接字通常只与同一个区域的套接字交换数据。 

套接字的类型 

1. 流式套接字(SOCK_STREAM) 

提供面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,且按发送的顺序接收,基于TCP协议 

2. 数据保式套接字(SOCK_DGRAM) 

提供无连接的服务,数据包以包形式发送,不提供无错误的保证,数据可能丢失或重复,且接收顺序混乱,基于UDP协议 

基于TCP(面向连接)的Socket编程 

服务器端顺序: 

1. 加载套接字库 

2. 创建套接字(socket) 

3. 将套接字绑定到一个本地地址和端口上(bind) 

4. 将套接字设为监听模式,准备接收客户请求(listen) 

5. 等待客户请求的到来;当请求带来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept) 

6. 用返回的套接字和客户端进行通信(send/recv) 

7. 返回,等待另一个客户请求 

8. 关闭套接字(closesocket) 

客户端程序: 

1. 加载套接字库 

2. 创建套接字(socket) 

3. 向服务器发送连接请求(connect) 

4. 和服务器端进行通信(send/receive) 

5. 关闭套接字(closesocket) 

基于UDP(面向无连接)的socket编程 

服务器端(接收端)程序: 

1. 加载套接字库 

2. 创建套接字(socket) 

3. 将套接字绑定到一个本地地址和端口上(bind) 

4. 等待接收数据(recvfrom) 

5. 关闭套接字(closesocket) 

客户端(发送端)程序 

1. 加载套接字库 

2. 创建套接字(socket) 

3. 向服务器发送数据(sendto) 

4. 关闭套接字(closesocket) 

创建基于TCP协议的CS程序的Server端所涉及的相关函数说明(按使用的先后顺序排列): 

1. int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData):作用是加载套接字库和进行套接字库的版本协商 

a. 参数wVersionRequested:用于指定准备加载的Winsock库的版本,高位字节指定所需要的Winsock库的副版本,低位字节则是主版本,可用MAKEWORD(X,Y)(其中,x为高位字节,y为低位字节)方便获得wVersionRequested的正确值。 

b. 参数lpWSAData:指向WSADATA结构的指针,WSAStartup用其加载的库版本有关的信息填在这个结构中 

2. SOCKET socket(int af,int type,int protocol): 

a. 参数af指定地址族,对于TCP/IP协议的套接字,它只能是AF_INET(也可写成PF_INET)。 

b. 参数type指定Socket类型,对于1.1版本的Socket,它只支持两种类型的套接字,SOCK_STREAM指定产生流式套接字,SOCK_DGRAM产生数据报套接字。 

c. 参数protocol与特定的地址家族相关的协议,如果指定为0,那么他就会根据地址格式和套接字类别,自动为你选择一个合适的协议。这是推荐使用的一种选择协议的方式。 

3. int bind(SOCKET s,const struct sockaddr FAR *name,int namelen) : 

a. 第一个参数指定要绑定的套接字,第二个参数指定该套接字的本地地址信息,是指向sockaddr结构的指针变量,由于该地址结构是为了所有的地址家族准备使用的,这个结构可能(通常会)随使用的网络协议不同而不同,所以,要用第三个参数指定该地址结构的长度。sockaddr机构定义如下: 

struct sockaddr 

u_short sa_family; 

char sa_data[14]; 

b. 上述结构第一个字段指定该地址家族,在这里必须设为AF_INET。sa_data仅仅是表示要求一块内存分配区,起到占位的作用,该区域中指定与协议相关的具体地址信息。由于实际要求的只是内存区,所以对于不同的协议家族,用不同的结构来替换sockaddr。在TCP/IP中,我们可以用 SOCKADDR_IN结构来代替sockaddr,以方便我们填写地址信息。 

c. struct SOCKADDR_IN{ 

short sin_family; 

unsigned short sin_port; 

struct in_addr sin_addr; 

char sin_zero[8]; 

}; 

sin_family 表示地址族,对于IP地址,sin_family成员将一直是AF_INET;成员sin_port指定的将要分配给套接字的端口;成员sin_addr 给出的是套接字的主机IP地址;sin_zero只是一个填充数,以使sockaddr_in结构和sockaddr结构的长度一样,一般不用设置。 

除了sin_family外,SOCKADDR_IN其他成员是按网络字节顺序表示的。所以需要进行转换:htonl(INADDR_ANY),htons(6000),其中6000是端口号。 

另外结构体的名称大写和小写指的是同一个。 

将 IP地址指定为INADDR_ANY,允许套接字向任何分配给本机器的IP地址发送或接收数据。一般一台机器一个网卡,但对于多网卡的机器,INADDR_ANY将简化应用程序的编写。将地址指定为INADDR_ANY,允许一个的应用接受发自多个接口的回应。如果我们只想让套接字使用多个IP中的一个地址,必须指定实际地址,要做到这一点,可以用inet_addr()函数,这个函数需要一个IP地址(如 192.168.80.88),返回一个适合分配给S_addr的u_long类型的数值。Inet_ntoa()函数完成相反的转换,它接受一个 in_addr结构体类型的参数并返回一个以点分十进制的IP地址字符串。 

htonl把一个u_long类型从主机字节序转换为网络字节序。 

htons把一个u_short类型从主机字节序转换为网络字节序。 

4. int listen(SOCKET s, int backlog):将套接字设置为监听模式,其中第二个参数设置等待请求连接的最大的值,即如果设置为n,则前n个请求会放置在系统的请求连接队列中,应用程序会依次对这些请求进行服务,但第n+1个连接请求则会被拒绝。 

5. SOCKET accept(SOCKET s, const struct sockaddr FAR * addr, int FAR* addrlen): 

从客户端接收请求,并创建连接,如果连接成功,则会返回一个当前成功建立连接的套接字,该套接字不是上面创建的监听套接字,而是仅仅适用于当前的一个请求连接,如果建立连接失败,则返回值是INVALID_SOCKET,并且可以适用WSAGetLastError()函数得到相关的失败信息,具体的 error code具体意义见MSDN中accept函数的最后部分的介绍 

6. send 函数:向客户端发送指定信息 

7. recv函数:得到从客户端传递过来的信息 

8. closesocket(SOCKET s):将指定的套接字关闭,从而释放资源 

9. WSACleanup():终止对winsocket库的使用 

10. hello 

服务器端的实现过程(Win32控制台程序): 

说明: 

1. 对于winsock库的类的使用,必须包含winsock2.h头文件 

2. 在setting中的link下的object/library modules中添加“ws2_32.lib”,注意和前面的字段之间用空格分隔 

3. 本服务器程序先于服务器端启动 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字(winsock)库,加载这段代码拷贝于MSDN中WSAStartup的介绍 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本号为1.1 

err = WSAStartup( wVersionRequested, &wsaData ); 

if ( err != 0 ) { 

return; 

if ( LOBYTE( wsaData.wVersion ) != 1 || 

HIBYTE( wsaData.wVersion ) != 1 ) { 

WSACleanup( ); 

return; 

//创建套接字 

SOCKET sockServer=socket(AF_INET,SOCK_STREAM,0); //SOCK_STREAM参数设置为TCP连接 

SOCKADDR_IN addrServer; //设置服务器端套接字的相关属性 

addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //设置IP 

addrServer.sin_family=AF_INET; 

addrServer.sin_port=htons(1234); //设置端口号 

//将套接字绑定到本地地址和指定端口上 

bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCK ADDR)); 

//将套接字设置为监听模式,并将最大请求连接数设置成5,超过此数的请求全部作废 

listen(sockServer,5); 

SOCKADDR_IN addrClient; //用来接收客户端的设置,包括IP和端口 

int len=sizeof(SOCKADDR); 

while(1) //不断监听 

//得到创建连接后的一个新的套接字,用来和客户端进行沟通,原套接字继续监听客户的连接请求 

SOCKET sockConn=accept(sockServer,(SOCKADDR*)&addrClient, &len); 

if(sockConn!=INVALID_SOCKET) //创建成功 

char sendInfo[100]; 

//inet_ntoa将结构转换为十进制的IP地址字符串 

sprintf(sendInfo,"welcome %s to this test!",inet_ntoa(addClient.sin_addr)); 

//成功建立连接后向客户端发送数据,结果将显示在客户端上 

send(sockConn,sendInfo,strlen(sendInfo)+1,0); 

//从客户端接收数据,结果显示在服务器上 

char recvInfo[100]; 

recv(sockConn,recvInfo,100,0); 

printf("%s\\n",recvInfo); 

//将本次建立连接中得到套接字关闭 

closesocket(sockConn); 

else 

int errCode=WSAGetLastError(); 

printf("the errcode is:%d\\n",errCode); 

//如果本程序不是死循环,那么在此处还应添加以下代码: 

closesocket(sockServer); //对一直处于监听状态的套接字进行关闭 

WSACleanup(); //终止对winsocket库的使用 

创建基于TCP协议的CS程序的Client端所涉及的相关函数说明(按使用的先后顺序排列): 

1. int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData):说明同上 

2. SOCKET socket(int af,int type,int protocol):说明同上 

3. connect函数:同服务器建立连接 

4. send/recv:发送与接收,同上 

5. closesocket:关闭套接字,同上

 

客户端的实现过程(win32 console程序): 

说明: 

1. 对于winsock库的类的使用,必须包含winsock2.h头文件 

2. 在setting中的link下的object/library modules中添加“ws2_32.lib”,注意和前面的字段之间用空格分隔 

3. 启动客户端程序之前必须先启动服务器端的程序 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字库 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本好为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); //SOCK_STREAM参数设置为TCP连接 

SOCKADDR_IN addrServer; //服务器地址结构 

addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0 .1"); //服务器地址 

addrServer.sin_port=htons(1234); //服务器端口号 

addrServer.sin_family=AF_INET; 

//与服务器端建立连接,进行通信 

int connReult=connect(sockClient,(SOCKADDR*)&addrServe r,sizeof(SOCKADDR)); 

if(connReult!=WSAEADDRNOTAVAIL) //访问成功 

//成功建立连接后向服务器端发送数据,结果将显示在服务器端上 

send(sockClient,"this is lisi!",strlen("this is zhangsan!")+1,0); 

//接收来自服务器端发送来的信息 

char recvInfo[100]; 

recv(sockClient,recvInfo,100,0); 

printf("%s\\n",recvInfo); 

else 

int errCode=WSAGetLastError(); 

printf("the errcode is:%d\\n",errCode); 

closesocket(sockClient); 

WSACleanup(); 

创建基于UPD的CS程序服务器端源代码: 

说明:服务器端的代码在XP下运行recvfrom函数执行不成功,返回一个10022的错误代码,参看网上资源,得知10022代表某个参数设置错误。 

花了大半天的时间研究后终于发现原来是6000端口在作怪,可能本机的UDP的6000端口在防火墙中被屏蔽了,通不过,但在TCP的CS程序中6000端口是通过的,程序调试一切正常,将端口修改为其他端口即可 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字(winsock)库,加载这段代码拷贝于MSDN中WSAStartup的介绍 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本号为1.1 

err = WSAStartup( wVersionRequested, &wsaData ); 

if ( err != 0 ) { 

return; 

if ( LOBYTE( wsaData.wVersion ) != 1 || 

HIBYTE( wsaData.wVersion ) != 1 ) { 

WSACleanup( ); 

return; 

//创建套接字 

//注意第二个参数和TCP设置不同 

SOCKET sockServer=socket(AF_INET,SOCK_DGRAM,0); 

SOCKADDR_IN addrServer; //设置服务器端套接字的地址结构的相关属性 

addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //设置IP 

addrServer.sin_family=AF_INET; 

addrServer.sin_port=htons(6000); //设置端口号 

//将套接字和服务器地址结构绑定 

bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCK ADDR)); 

SOCKADDR_IN addrClient; 

int len=sizeof(SOCKADDR); 

char buffer[100]; 

//从客户端接收数据 

int result=recvfrom(sockServer,buffer,100,0,(SOCKADDR* )&addrClient,&len); 

if(result==SOCKET_ERROR) 

int errCode=WSAGetLastError(); 

printf("error:%d",errCode); 

else 

printf("this message from client:%s\\n",buffer); 

closesocket(sockServer); 

WSACleanup(); 

创建基于UDP的CS程序客户端的代码: 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字(winsock)库,加载这段代码拷贝于MSDN中WSAStartup的介绍 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本号为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); //注意第二个参数和TCP设置不同 

SOCKADDR_IN addrServer; //服务器地址结构 

addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0 .1"); //服务器地址 

addrServer.sin_family=AF_INET; 

addrServer.sin_port=htons(6000); //服务器端口号 

sendto(sockClient,"this message from client",strlen("this message from client")+1,0,(SOCKADDR*)&addrServer,sizeof(SOCKADD R)); 

closesocket(sockClient); 

WSACleanup(); 

基于UDP的聊天程序服务器端源程序: 

说明: 

1. 代码基本和上述UDP服务器端的程序相类似,只是多了sendto功能,即交互的功能 

2. 支持退出请求响应 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字(winsock)库,加载这段代码拷贝于MSDN中WSAStartup的介绍 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本号为1.1 

err = WSAStartup( wVersionRequested, &wsaData ); 

if ( err != 0 ) { 

return; 

if ( LOBYTE( wsaData.wVersion ) != 1 || 

HIBYTE( wsaData.wVersion ) != 1 ) { 

WSACleanup( ); 

return; 

//创建套接字 

//注意第二个参数和TCP设置不同 

SOCKET sockServer=socket(AF_INET,SOCK_DGRAM,0); 

SOCKADDR_IN addrServer; //设置服务器端套接字的地址结构的相关属性 

addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //设置IP 

addrServer.sin_family=AF_INET; 

addrServer.sin_port=htons(6000); //设置端口号 

//将套接字和服务器地址结构绑定 

bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCK ADDR)); 

SOCKADDR_IN addrClient; 

int len=sizeof(SOCKADDR); 

char recvBuf[100]; 

char tempBuf[100]; 

char sendBuf[100]; 

while(1) 

//从客户端接收数据 

int result=recvfrom(sockServer,recvBuf,100,0,(SOCKADDR *)&addrClient,&len); 

if(result==SOCKET_ERROR) 

int errCode=WSAGetLastError(); 

printf("error:%d",errCode); 

break; //退出循环 

else 

if(recvBuf[0]=='q') //对方请求退出 

//同样将退出请求发送回去 

sendto(sockServer,"q",strlen("q")+1,0,(SOCKADDR*)& addrClient,sizeof(SOCKADDR)); 

printf("the chat end!"); 

break; 

else 

//将对方发送过来的信息前段加上IP地址进行输出 

sprintf(tempBuf,"%s said:%s",inet_ntoa(addrClient.sin_addr),recvBuf); 

printf("%s\\n",tempBuf); 

//将用户的键盘输入发送到对方 

printf("pleas input the message:\\n"); 

gets(sendBuf); //得到键盘输入内容 sendto(sockServer,sendBuf,strlen(sendBuf)+1,0,(SOC KADDR*)& addrClient,sizeof(SOCKADDR)); 

closesocket(sockServer); 

WSACleanup(); 

基于UDP的聊天程序客户端端源程序: 

#include "winsock2.h" 

#include "stdio.h" 

void main() 

//加载套接字(winsock)库,加载这段代码拷贝于MSDN中WSAStartup的介绍 

WORD wVersionRequested; 

WSADATA wsaData; 

int err; 

wVersionRequested = MAKEWORD( 1, 1 ); //版本号为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); //注意第二个参数和TCP设置不同 

SOCKADDR_IN addrServer; //服务器地址结构 

addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0 .1"); //服务器地址 

addrServer.sin_family=AF_INET; 

addrServer.sin_port=htons(6000); //服务器端口号 

char tempBuf[100]; 

char recvBuf[100]; 

char sendBuf[100]; 

int len=sizeof(SOCKADDR); 

while(1) 

printf("plese input the message:\\n"); 

gets(sendBuf); //得到用户的键盘输入 

sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOC KADDR*)&addrServer,sizeof(SOCKADDR)); 

int result=recvfrom(sockClient,recvBuf,100,0,(SOCKADDR *)&addrServer,&len); 

if(result==SOCKET_ERROR) 

int errCode=WSAGetLastError(); 

printf("error:%d",errCode); 

break; //退出循环 

else 

if(recvBuf[0]=='q') //对方请求退出 

//同样将退出请求发送回去 

sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)& addrServer,sizeof(SOCKADDR)); 

printf("the chat end!"); 

break; 

else 

//将对方发送过来的信息前段加上IP地址进行输出 

sprintf(tempBuf,"%s said:%s",inet_ntoa(addrServer.sin_addr),recvBuf); 

printf("%s\\n",tempBuf); 

closesocket(sockClient); 

WSACleanup(); 

几点心得: 

1. sendto和recvfrom函数中第四个类型为struct sockaddr FAR*的参数一般采用SOCKADDR_IN结构类型,且都是对方的SOCKADDR_IN数据: 

如在服务器端,因为定义了自身的SOCKADDR_IN addrServer,其中的结构参数进行了具体设置,其中IP地址一项是设置为自动选择自己的网卡,且将套接字和该结构体进行了绑定,然后申明了一个空的SOCKADDR_IN addClient,即对其中的结构参数不做任何的初始化,但没有关系,recvfrom方法调用在前,能得到客户端的详细信息(这有点坐享其成的感觉,服务器端就是等着先由客户端发送消息过来),将addClient填充满,然后调用sendto方法时,该结构体已经具有是客户端的信息了,所以 sendto的时候是正确的。服务器端接收和发送调用的地址结构参数都是客户端的。 

在客户端,定义了服务器端的地址结构,其中IP地址一项,填写的就是具体的目标服务器地址,发送和接收都是有针对性的,sendto在前先发送消息到服务器,地址参数是服务器端的,然后revefrom接收消息,地址参数也是服务器的。客户端接收和发送调用的地址结构参数都是服务器端的。 

2. 本例子中的聊天室程序有一个缺陷,就是必须服务端先启,然后客户端启动,并且得先由客户端发送消息过来后,服务器端才能知道到底是谁发送消息来了,然后将有关信息按先前发送过来的相关地址信息发送回去。对于客户端,因为已经在地址结构中设置了服务器的IP地址,所以发送是有目的性的。综上就是先有客户端发送消息,再服务器端发送消息,然就是交替进行了。 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/roger_ge/archive/2008/09/07/2 6545.aspx 

很抱歉,因为您在网易相册发布了违规信息,账号被屏蔽。被屏蔽期间他人无法访问您的相册。 

去帮助中心,了解如何重新恢复服务。 

http://www.vckbase.com 

  

[   原创文档   本文适合中级读者   已阅读7134次   ] 

用udp协议通讯示例 

作者:fs007 

下载源代码 

一、绪言 

  udp是一种面向非连接,不可靠的通讯协议,相对于tcp来说,虽然可靠性不及,但传输效率较高。所以在网络上仍有很大的用途。这几日需要了解下udp通讯的过程,上网发现这方面的资料还挺少。于是仔细的翻找了下msdn,基本上搞清楚了udp通讯的过程。做了一个测试的例子。希望对大家有帮助。 

二、udp的通讯过程 

server端:   open a   socket(socket)---> name   the   socket(bind)---> send   and   receive   data(sendto   recvfrom)---> close   socket(closesocket)

client端:   open   a   socket(socket)----------------------------> send   and   receive   data(sendto   recvfrom)---> close   socket(closesocket)

  server端无需listen,client端无需connect,因此udp中server和client的区别相对较模糊。只要调用sendto和recvfrom就可以给指定的地址收发数据,但并不保证收发的数据的完整性和可靠性。 

三、示例 

  udpserver主要代码:   

void   main() 

SOCKET   socket1; 

InitWinsock(); 

struct   sockaddr_in   local; 

struct   sockaddr_in   from; 

int   fromlen   =sizeof(from); 

local.sin_family=AF_INET; 

local.sin_port=htons(1000);                           ///监听端口 

local.sin_addr.s_addr=INADDR_ANY;               ///本机 

socket1=socket(AF_INET,SOCK_DGRAM,0); 

bind(socket1,(struct   sockaddr*)&local,sizeof   local); 

while   (1) 

char   buffer[1024]= "\\0 "; 

printf( "waiting   for   message   from   others-------------\\n "); 

if   (recvfrom(socket1,buffer,sizeof   buffer,0,(struct   sockaddr*)&from,&fromlen)!=SOCKET_ERROR) 

printf( "Received   datagram   from   %s--%s\\n ",inet_ntoa(from.sin_addr),buffer); 

////给cilent发信息 

sendto(socket1,buffer,sizeof   buffer,0,(struct   sockaddr*)&from,fromlen); 

Sleep(500); 

closesocket(socket1); 

udpcilent主要代码:   void   main() 

SOCKET   socket1; 

InitWinsock(); 

struct   sockaddr_in   server; 

int   len   =sizeof(server); 

server.sin_family=AF_INET; 

server.sin_port=htons(1000);                                             ///server的监听端口 

server.sin_addr.s_addr=inet_addr( "168.168.0.10 ");   ///server的地址   

socket1=socket(AF_INET,SOCK_DGRAM,0); 

while   (1) 

char   buffer[1024]= "\\0 "; 

printf( "input   message\\n "); 

scanf( "%s ",buffer); 

if   (strcmp(buffer, "bye ")==0) 

break; 

if   (sendto(socket1,buffer,sizeof   buffer,0,(struct   sockaddr*)&server,len)!=SOCKET_ERROR) 

if   (recvfrom(socket1, 

                                                                                buffer, 

                                                                                sizeof   buffer, 

                                                                                0, 

                                                                                (struct   sockaddr*)&server,&len)   !=   SOCKET_ERROR) 

printf( "rece   from   server:%s\\n ",buffer); 

closesocket(socket1); 

四、结束语   

  udp通讯比tcp简单了很多,在数据可靠性不是很高的情况下,有使用的价值。  

文档

基于TCP和UDP的Socket编程

基于TCP和UDP的Socket编程在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信,对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息UDP:是无连接的在OSI的各层所使用的协议:1.应用层:telnet,FTP,HTTP,DNS,SMTP,POP32.传输层:TCP,UDPTCP:面向连接的可靠的传输协议,通信前建立三次握手
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top