导航:首页 > IDC知识 > udpsocket服务器

udpsocket服务器

发布时间:2021-01-13 04:42:29

1、简述基于TCP和UDP的Socket编程的异同

Socket有两种主要的操作方式:面向连接的和无连接的。无连接的操作使用UDP数据报协议,这个操作不需要连接一个目的的socket,它只是简单地投出数据报,快速高效,但缺少数据安全性。面向连接的操作使用TCP协议,一个这个模式的socket必须在发送数据之前与目的地的socket取得一个连接,一旦连接建立了,socket就可以使用一个流接口:打开-读-写-关闭,所有的发送的信息都会在另一端以同样的顺序被接收,面向连接的操作比无连接的操作效率要低,但数据的安全性更高。基于TCP的socket编程是采用的流式套接字(SOCK_STREAM)。基于UDP采用的数据报套接字(SOCK_DGRAM).
流式套接字的设计是针对面向连接的网络应用,在数据传输之前需要预先建立连接,在数据传输过程中需要维持连接,在数据传输结束后需要释放连接。由于采用校验和、确认与超时等差错控制手段,因此流式套接字可以保证数据传输的正确性。
数据报套接字(SOCK_DGRAM)提供无连接的、不可靠的数据传输服务,实际上它是基于TCP/IP协议族中的UDP协议实现的。数据报套接字提供无序、有差错与有重复的数据流服务。数据报套接字的设计是针对无连接的网络应用,在数据传输之前不需要预先建立连接。由于只采用很有限的差错控制手段,因此数据报套接字无法保证数据传输的正确性。

2、udp服务器怎么创建多个socket描述符

DP 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

3、Linux客户端和Window服务器端udp socket通信不能成功

上面代码没问题,用Linux虚拟机和window调试时,不能选用Bridge方式,改用NAT方式即可。
因为系统环境专不同,这样属慢慢地很容易就找到问题出在哪里,打个比方?触发了里面有什么内容,它发送一条消息少年。这类问题(是打比方,精确到端口,语言不同。打印出来看,一步一步排查就行,不限于这一个问题)
另外的可能就是linux客户端上的代码运行机制问题。
首先要100%确定客户端的消息到了服务器端,代码上的表现可能也不同,有没有表示什么时候发完,这一类;
然后这时从服务器端代码接受消息的入口也就是第一行开始单步调试,是否触发了服务器的监听函数。也就是结束符,服务器可能一直在等单条消息的结束

4、html5的websocket怎么建立udp连接

这个没有办法的,因为Websocket是基于TCP协议的。推荐使用WebRTC ,它是基于UDP协议的。

5、socket/udp 客户端程序运行刚运行的时候可以接收服务器发送的udp消息,但是过了一小会之后就无法收到消息

因为你发送过去 对方接收到的是你发送的端口 如果对方马上回复的回话 你这个端口是处于监答听状态 信息也能收到 但过了一会儿 这个端口就被回收了 所以你要做的是 当你把消息发送过去的时候 在消息里加入你现在一直处于监听的那个端口 让对方知道 我这个端口一直处于监听状态的 这样的话 对方把消息发到这个端口上 几个小时之后也能收到了 用用我的吧 已经封装好了的 http://www.cnblogs.com/SanNiuSignal/p/3812843.html

6、UDP 和 TCP 的 socket 分别一般用在什么地方

UDP 的使用范围很窄,而且编程比 TCP 难多了:

你真的很在乎延迟,不能忍受重传,那么就用UDP,例如 NTP 协议。重传NTP消息纯属添乱。
你真的不在乎可靠性,丢一些包也不需要重传,那么就可以用 UDP。例子我想不出来。有人说音频或视频流可以用UDP,不过据我看来各大视频网站都用HTTP协议,而HTTP是基于TCP的。
你需要NAT穿透,那么不得不用UDP。
其他情况,一旦程序要自己做重传,你都是在用UDP模拟出蹩脚的TCP,还不如直接用TCP呢。
总之:使用 UDP 需要有强大到不容置疑的理由,when in doubt, use TCP.

一些协议,出于历史原因,受当时技术和网络条件限制,选择了基于UDP实现,其选择的理由现在很可能已经不再成立了。因此“xxx协议用UDP”不是你现在写网络应用程序也该用UDP的理由,除非你本身就是在实现xxx协议。

另外,那些说TCP比UDP慢、效率低的,你拿UDP写个程序,把千兆网带宽打满(TCP等价的代码只有两行:客户端 while (true) { send(...); } 服务端 while (true) { recv(...); }。),且不说你的程序会有多复杂,先看看goodput到底是不是比TCP大、CPU使用率是不是比TCP低嘛。

7、怎么写一个socket编程,不管是udp的还是tcp的,可以不在同一个局域网中通信?

网络通讯很简单的道理 通许必须有一方是公网地址 这个所谓的公网地址简单理解就是互联网上内公开的地容址,能够背直接访问的IP地址
那么你如果想实现中国到美国的通讯(下面简称2方通讯)方法有一下几种
方法1:
中国这边或者美国那边至少一方是具有公网IP地址的 具有公网地址的作为服务端 另外一方作为客户端连接(具体实现就是公网一方监听自己的公网地址上的某个端口 客户端直接连接对方的公网地址跟端口即可)( A<=====>B(公网地址) )
方法2:
2方都具有公网地址 那就更简单 互相连接对方的公网地址跟端口即可(A(公网)<======>B(公网))
方法3:
2方都没有公网地址(但是其中一方或者双方都能在路由器上做端口映射 这个问题就转化成了方法2 或者方法1)(A(端口映射)<===========B)
方法4:
2方都没有公网地址也无法做端口映射 这个时候就要假设一个中转的服务器 2方都去连接那个中转服务器 通过服务来转发消息(A(内网)<===============(消息中转服务器)============>B(内网))
目前QQ就是用的这样的消息传送方式

8、UDP和Socket通信步骤

UDP Server程序
1、编写UDP Server程序的步骤
(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。
(2)初始化_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的错误信息。

9、UDP socket最多并发多少连接

根据你的描述:
并发连接是TCP的概念,UDP只管收发数据。
要支持尽量多的终端,服务器的处理效率要够快,另外尽量避免多终端同时发送数据。

10、socket中tcp/ip和udp的区别

一、TCP与UDP的区别
基于连接与无连接
对系统资源的要求(TCP较多,UDP少)
UDP程序结构较简单
流模式与数据报模式
TCP保证数据正确性,UDP可能丢包
TCP保证数据顺序,UDP不保证
部分满足以下几点要求时,应该采用UDP 面向数据报方式 网络数据大多为短消息
拥有大量Client
对数据安全性无特殊要求
网络负担非常重,但对响应速度要求高
具体编程时的区别 socket()的参数不同
UDP Server不需要调用listen和accept
UDP收发数据用sendto/recvfrom函数
TCP:地址信息在connect/accept时确定
UDP:在sendto/recvfrom函数中每次均 需指定地址信息
UDP:shutdown函数无效
二、man----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

三、编程区别
通常我们在说到网络编程时默认是指TCP编程,即用前面提到的socket函数创建一个socket用于TCP通讯,函数参数我们通常填为SOCK_STREAM。即socket(PF_INET, SOCK_STREAM, 0),这表示建立一个socket用于流式网络通讯。
  SOCK_STREAM这种的特点是面向连接的,即每次收发数据之前必须通过connect建立连接,也是双向的,即任何一方都可以收发数据,协议本身提供了一些保障机制保证它是可靠的、有序的,即每个包按照发送的顺序到达接收方。

而SOCK_DGRAM这种是User Datagram Protocol协议的网络通讯,它是无连接的,不可靠的,因为通讯双方发送数据后不知道对方是否已经收到数据,是否正常收到数据。任何一方建立一个socket以后就可以用sendto发送数据,也可以用recvfrom接收数据。根本不关心对方是否存在,是否发送了数据。它的特点是通讯速度比较快。大家都知道TCP是要经过三次握手的,而UDP没有。

基于上述不同,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、关闭网络连接;

与udpsocket服务器相关的知识