关于socket通信的信息

http://www.itjxue.com  2023-01-14 05:58  来源:未知  点击次数: 

Socket通信(基本格式)

Socket通信是基于TCP/IP协议的通信。属于C/S结构(就是有客户端和移动端两部分的结构)

注解:TCP/IP ?面向连接?

? ? ? ? ? ? UDP ? ? ?面向非连接

服务端:

1.创建服务器

ServerSocket ss=new ServerSocket(PORT);

2.等待客户端连接

Socket s=ss.accept();

3. 与客户端通信:

获取到输出流或者输入流,进行读取或者发送数据

4.关闭

客户端:

1.创建连接

Socket s=new Socket(IP,PORT);

注解:这里的IP是服务器的IP 这里的PORT是服务器创建的PORT

2.与服务器通信

获取到输出流或者输入流,进行读取或者发送数据

3.关闭

简述Socket(套接字)通信

所谓Socket就是套接字,套接字就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。

一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。

一、Socket(套接字)简介:

Socket(套接字)是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。可以将Socket(套接字)看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。Socket(套接字)存在于通信域中,通信域是为了处理一般的线程通过Socket(套接字)通信而引进的一种抽象概念。Socket(套接字)通常和同一个域中的Socket(套接字)交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。

Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个Socket(套接字)都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket(套接字)中,该 Socket(套接字)通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket(套接字)中,使对方能够接收到这段信息。 Socket(套接字)是由IP地址和端口结合的,提供向应用层进程传送数据包的机制。

二、Socket(套接字)表达方式:

Socket(套接字)=(IP地址:端口号),套接字的表示方法是点分十进制的lP地址后面写上端口号,中间用冒号或逗号隔开。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。

例如: 如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)。

三、Socket(套接字)的主要类型:

1.流套接字(SOCK_STREAM)

流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。

2.数据报套接字(SOCK_DGRAM)

数据报套接字提供一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP( User DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。

3.原始套接字(SOCK_RAW)

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送的数据必须使用原始套接。

要通过互联网进行通信,至少需要一对套接字,其中一个运行于客户端,我们称之为 Client Socket,另一个运行于服务器端,我们称之为 Server Socket。

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:

服务器监听

客户端请求

连接确认

1.服务器监听

所谓服务器监听,是指服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

2.客户端请求

所调客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端接字提出连接请求。

3.连接确认

所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,就会响应客户端套接字的请求,建立一个新的线程,并把服务器端套接字的描述发送给客户端。一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,接收其他客户端套接字的连接请求。

根据套接字的不同类型,可以将套接字调用分为面向连接服务和无连接服务。

面向连接服务的主要特点如下:

(1)数据传输过程必须经过建立连接、维护连接和释放连接3个阶段;

(2)在传输过程中,各分组不需要携带目的主机的地址;

(3)可靠性好,但由于协议复杂,通信效率不高。

面向无连接服务的主要特点如下:

(1)不需要连接的各个阶段;

(2)每个分组都携带完整的目的主机地址,在系统中独立传送;

(3)由于没有顺序控制,所以接收方的分组可能出现乱序、重复和丢失现象;

(4)通信效率高,但可靠性不能确保。

UDP和Socket通信步骤是什么?

UDP Server程序\x0d\x0a1、编写UDP Server程序的步骤\x0d\x0a(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(2)初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义:\x0d\x0astruct sockaddr_in {\x0d\x0auint8_t sin_len;\x0d\x0asa_family_t sin_family;\x0d\x0ain_port_t sin_port;\x0d\x0astruct in_addr sin_addr;\x0d\x0achar sin_zero[8];\x0d\x0a};\x0d\x0a这里使用“08”作为服务程序的端口,使用“INADDR_ANY”作为绑定的IP地址即任何主机上的地址。\x0d\x0a(3)使用bind()把上面的socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。\x0d\x0a(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。\x0d\x0a\x0d\x0a2、udpserv.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)\x0d\x0a{\x0d\x0aint n;\x0d\x0asocklen_t len;\x0d\x0achar mesg[MAXLINE];\x0d\x0a\x0d\x0afor(;;)\x0d\x0a{\x0d\x0alen = clilen;\x0d\x0a/* waiting for receive data */\x0d\x0an = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, len);\x0d\x0a/* sent data back to client */\x0d\x0asendto(sockfd, mesg, n, 0, pcliaddr, len);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in servaddr, cliaddr;\x0d\x0a\x0d\x0asockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */\x0d\x0a\x0d\x0a/* init servaddr */\x0d\x0abzero(servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family = AF_INET;\x0d\x0aservaddr.sin_addr.s_addr = htonl(INADDR_ANY);\x0d\x0aservaddr.sin_port = htons(SERV_PORT);\x0d\x0a\x0d\x0a/* bind address and port to socket */\x0d\x0aif(bind(sockfd, (struct sockaddr *)servaddr, sizeof(servaddr)) == -1)\x0d\x0a{\x0d\x0aperror("bind error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0ado_echo(sockfd, (struct sockaddr *)cliaddr, sizeof(cliaddr));\x0d\x0a\x0d\x0areturn 0;\x0d\x0a}\x0d\x0a\x0d\x0aUDP Client程序\x0d\x0a1、编写UDP Client程序的步骤\x0d\x0a(1)初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。\x0d\x0a(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(3)使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面我们说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。\x0d\x0a(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。\x0d\x0a(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。\x0d\x0a(6)处理接收到的数据,这里是直接输出到标准输出上。\x0d\x0a\x0d\x0a2、udpclient.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)\x0d\x0a{\x0d\x0aint n;\x0d\x0achar sendline[MAXLINE], recvline[MAXLINE + 1];\x0d\x0a\x0d\x0a/* connect to server */\x0d\x0aif(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)\x0d\x0a{\x0d\x0aperror("connect error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0awhile(fgets(sendline, MAXLINE, fp) != NULL)\x0d\x0a{\x0d\x0a/* read a line and send to server */\x0d\x0awrite(sockfd, sendline, strlen(sendline));\x0d\x0a/* receive data from server */\x0d\x0an = read(sockfd, recvline, MAXLINE);\x0d\x0aif(n == -1)\x0d\x0a{\x0d\x0aperror("read error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0arecvline[n] = 0; /* terminate string */\x0d\x0afputs(recvline, stdout);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(int argc, char **argv)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in srvaddr;\x0d\x0a\x0d\x0a/* check args */\x0d\x0aif(argc != 2)\x0d\x0a{\x0d\x0aprintf("usage: udpclient \n");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0a/* init servaddr */\x0d\x0abzero(servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family = AF_INET;\x0d\x0aservaddr.sin_port = htons(SERV_PORT);\x0d\x0aif(inet_pton(AF_INET, argv[1], servaddr.sin_addr)

回答于?2022-11-17

(责任编辑:IT教学网)

更多