http://jimmee.iteye.com/blog/617110

http://jimmee.iteye.com/category/93740

Java TCP/IP Socket 编程 笔记(一)—基本概念

  • 博客分类:
  • J2SE
编程SocketJava网络协议网络应用
一些概念:
通信信道(communication channel):将字节序列从一个主机传输到另一个主机的一种手段,可能是有线电缆,如以太网(Ethernet),也可能是无线的,如WiFi,或是其他方式的连接。

信息(information)是指由程序创建和解释的字节序列。在计算机网络环境中,这些字节序列称为分组报文(packet)。

协议(protocol)相当于相互通信的程序达成的一种约定,它规定了分组报文的交换方式和它们包含的意义。一组协议规定了分组报文的结构(例如报文中的哪一部分表明了目的地址)以及怎样对报文中所包含的信息进行解析。

TCP和UDP属于传输层,IP属于网络层,TCP,UDP和IP的具体实现通常驻留在主机的操作系统中。应用程序通过套接字API对UDP协议和TCP协议所提供的服务进行访问。

IP协议提供了一种数据报服务:每组分组报文都由网络独立处理和分发,就像信件或包裹通过邮政系统发送一样。IP报文必须包含一个保存其目的地址的字段,就像你所投递的每份包裹都写明了收件人地址一样。

TCP协议和UDP协议使用的地址叫做端口号,都是用来区分同一主机中的不同应用程序的。

客户端(client)是通信的发起者,而服务器(server)程序则被动等待客户端发起通信,并对其作出响应。

一个程序是作为客户端还是服务器,决定了它在与其对等端(peer)建立通信时使用的套接字API(客户端的对等端是服务器,反之亦然)。客服端必须首先知道服务器端的地址和端口号,反之则不需要。这个打电话类似。只要通信连接建立成功,服务器和客户端之间就没有区别了。

Socket(套接字)是一种抽象层,应用程序通过它来发送和接受数据,就像应用程序打开一个文件句柄,将数据读写到稳定的存储器上一样。一个TCP/IP套接字由一个互联网地址,一个端对端协议(TCP或UDP协议)以及一个端口号唯一确定。

Java TCP/IP Socket 编程 笔记(二)—TCP的例子

  • 博客分类:
  • J2SE
编程SocketJava网络协议
1.InetAddress类和SocketAddress用于识别网络主机
TCP协议客户端和服务器端的套接字为Socket和ServerSocket
UDP协议的客户端和服务器端的套接字为DatagramSocket

2.
类 NetworkInterface表示一个由名称和分配给此接口的 IP 地址列表组成的网络接口,其getNetworkInterfaces()返回此机器上的所有接口。getInetAddresses()是返回一个 Enumeration 并将所有 InetAddress 或 InetAddress 的子集绑定到此网络接口的便捷方法。(注意:一个网络接口可能包含IPv4或IPv6地址)

3.类 InetAddress的getHostAddress()返回 IP 地址字符串(以文本表现形式)。 getAllByName(String host)在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。getHostName()获取此 IP 地址的主机名。getHostAddress() 返回 IP 地址字符串(以文本表现形式)。

4.TCP套接字
服务器端ServerSocket实例监听TCP链接请求,并为每个请求创建新的Socket实例。也就是说,服务器端要同时处理ServerSocket实例和Sockete实例,而客户端只需要使用Socket实例。

TCP客户端:

Java代码  
  1. public class TCPEchoClient {
  2. public static void main(String [] args) throws UnknownHostException, IOException, InterruptedException {
  3. if(args.length<2||args.length>3){
  4. throw new IllegalArgumentException("Parameter(s):<Server> <Word> [<Port>]");
  5. }
  6. String server=args[0];
  7. byte [] data=args[1].getBytes();
  8. int servPort=(args.length==3)?Integer.parseInt(args[2]):7;
  9. //1.创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接
  10. Socket socket=new Socket(server,servPort);
  11. System.out.println("Connected to server... sending echo string");
  12. /**
  13. *2. 通过套接字的输入输出流进行通信:一个Socket连接实例包括一个InputStream和一个OutputStream,它们的用法同于其他Java输入输出流。
  14. */
  15. InputStream in=socket.getInputStream();
  16. OutputStream out=socket.getOutputStream();
  17. out.write(data);
  18. int totalBytesRcvd=0;
  19. int bytesRcvd;
  20. while(totalBytesRcvd<data.length){
  21. if((bytesRcvd=in.read(data, totalBytesRcvd, data.length-totalBytesRcvd))==-1){
  22. throw new SocketException("Connection closed prematurely");
  23. }
  24. totalBytesRcvd+=bytesRcvd;
  25. }
  26. System.out.println("Receved: "+new String(data));
  27. //3.使用Socet类的close()方法关闭连接
  28. socket.close();
  29. }
  30. }
public class TCPEchoClient {
public static void main(String [] args) throws UnknownHostException, IOException, InterruptedException {
if(args.length<2||args.length>3){
throw new IllegalArgumentException("Parameter(s):<Server> <Word> [<Port>]");
}
String server=args[0];
byte [] data=args[1].getBytes();
int servPort=(args.length==3)?Integer.parseInt(args[2]):7;
//1.创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接
Socket socket=new Socket(server,servPort);
System.out.println("Connected to server... sending echo string");
/**
*2. 通过套接字的输入输出流进行通信:一个Socket连接实例包括一个InputStream和一个OutputStream,它们的用法同于其他Java输入输出流。
*/
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
out.write(data);
int totalBytesRcvd=0;
int bytesRcvd;
while(totalBytesRcvd<data.length){
if((bytesRcvd=in.read(data, totalBytesRcvd, data.length-totalBytesRcvd))==-1){
throw new SocketException("Connection closed prematurely");
}
totalBytesRcvd+=bytesRcvd;
}
System.out.println("Receved: "+new String(data));
//3.使用Socet类的close()方法关闭连接
socket.close();
}
}

TCP服务器端代码:

Java代码  
  1. public class TCPEchoServer {
  2. private static final int BUFSIZE=32;
  3. public static void main(String [] args) throws IOException, InterruptedException{
  4. if(args.length!=1){
  5. throw new IllegalArgumentException("Parameter(s):<Port>");
  6. }
  7. int servPort=Integer.parseInt(args[0]);
  8. //1.创建一个ServerSocket实例并制定本地端口。此套接字的功能是侦听该制定端口收到的连接。
  9. ServerSocket servSock=new ServerSocket(servPort);
  10. int recvMsgSize;
  11. byte [] receiveBuf=new byte[BUFSIZE];
  12. //2.重复执行
  13. while(true){
  14. //a.调用ServerSocket的accept()方法以获取下一个客户端连接。
  15. //基于新建立的客户端连接,创建一个Socket实例,并由accept()方法返回
  16. Socket clntSock=servSock.accept();
  17. SocketAddress clientAddress=clntSock.getRemoteSocketAddress();
  18. System.out.println("Handling client at "+clientAddress);
  19. //b,使用所返回的Socket实例的InputStream和OutputStream与客户端进行通信
  20. InputStream in=clntSock.getInputStream();
  21. OutputStream out=clntSock.getOutputStream();
  22. while((recvMsgSize=in.read(receiveBuf))!=-1){
  23. out.write(receiveBuf, 0, recvMsgSize);
  24. }
  25. //c,通信完成后,使用Socket的close()方法关闭该客户端套接字链接
  26. clntSock.close();
  27. }
  28. }
  29. }

Java TCP/IP Socket 编程 笔记(三)—UDP的例子

1.UDP套接字与TCP套接字不同。UDP套接字在使用前不需要进行连接。TCP协议与电话通信相似,而UDP协议则与邮件通信相似:你寄包裹或信件时不要进行“连接”,但是你的为每个包裹和信件制定目的地址。类似地,每条信息(datagram,即数据报文)负载了自己的地址信息,并与其他信息相互独立。在接收信息时,UDP套接字扮演的角色就像是一个信箱,从不同地址发送来的信件和包裹都可以放到里面。一旦被创建,UDP套接字就可以用来连续地向不同的地址发送消息,或从任何地址接收信息。
UDP套接字将保留边界信息。UDP不像TCP一样,它是尽可能地传送消息,但并不保证信息一定能成功到达目的地址,而且信息到达的顺序与其发送顺序不一定一致(就像通过邮政部分寄信一样)。因此,UDP套接字的程序必须准备好处理信息的丢失和重排。
UDP的优点之一是效率较高,其次是灵活性。

Java通过DatagramPacket类和DatagramSocket类来使用UDP套接字。客户端和服务端都使用DatagramSocket来发送数据,使用DatagramPacket来接收数据。

发送信息时,Java程序创建一个包含了待发送信息的DatagramPacket实例,并将其作为参数传递给DatagramSocket类的send()方法。接收信息时,Java程序首先创建一个DatagramPacket类的实例,该实例中预先分配了一些空间(一个字节数组byte[]),并将接收到的信息存放在该空间中。然后把该实例作为参数传递给DatagramSocket类的receive()方法。

DatagramPacket的内部有length和offset字段,如果指定了offset,数据报文的数据部分将从字节数组的指定位置发送或接收数据。length参数指定了字节数组中在发送时要传输的字节数,活在接收数据时所能接收的最多字节数。length要比data.length小,但不能比它大。

UDP客户端:

Java代码  
  1. import java.io.IOException;
  2. import java.io.InterruptedIOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.InetAddress;
  6. public class UDPEchoClientTimeout {
  7. private static final int TIMEOUT=3000;
  8. private static final int MAXTRIES=5;
  9. public static void main(String[] args) throws IOException {
  10. if(args.length<2||args.length>3){
  11. throw new IllegalArgumentException("Parameter(s):<Server> <Word> [<Port>]");
  12. }
  13. InetAddress serverAddress=InetAddress.getByName(args[0]);//server address;
  14. byte [] bytesToSend=args[1].getBytes();
  15. int servPort=(args.length==3)?Integer.parseInt(args[2]):7;
  16. //1.创建一个DatagramSocket实例,可以选择对本地地址和端口进行设置。
  17. DatagramSocket socket=new DatagramSocket();
  18. //设置receive()方法的最长阻塞时间
  19. socket.setSoTimeout(TIMEOUT);
  20. DatagramPacket sendPacket=new DatagramPacket(bytesToSend,bytesToSend.length,serverAddress,servPort);
  21. DatagramPacket receivePacket=new DatagramPacket(new byte[bytesToSend.length],bytesToSend.length);
  22. int tries=0;
  23. boolean receivedResponse=false;
  24. do{
  25. //2.使用DatagramSocket类的send()和receive()方法来发送和接收DatagramPacket实例,进行通信
  26. socket.send(sendPacket);
  27. try{
  28. socket.receive(receivePacket);
  29. if(!receivePacket.getAddress().equals(serverAddress)){
  30. throw new IOException("Received packet from an unknown source");
  31. }
  32. receivedResponse=true;
  33. }catch(InterruptedIOException e){
  34. tries+=1;
  35. System.out.println("Timed out,"+(MAXTRIES-tries)+" more tries ...");
  36. }
  37. }while(!receivedResponse&&(tries<MAXTRIES));
  38. if(receivedResponse){
  39. System.out.println("Received: "+new String(receivePacket.getData()));
  40. }else{
  41. System.out.println("No response -- giving up.");
  42. }
  43. //3.通信完成后,使用DatagramSocket类的close方法来销毁该套接字
  44. socket.close();
  45. }
  46. }
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPEchoClientTimeout {
private static final int TIMEOUT=3000;
private static final int MAXTRIES=5;
public static void main(String[] args) throws IOException {
if(args.length<2||args.length>3){
throw new IllegalArgumentException("Parameter(s):<Server> <Word> [<Port>]");
}
InetAddress serverAddress=InetAddress.getByName(args[0]);//server address;
byte [] bytesToSend=args[1].getBytes();
int servPort=(args.length==3)?Integer.parseInt(args[2]):7;
//1.创建一个DatagramSocket实例,可以选择对本地地址和端口进行设置。
DatagramSocket socket=new DatagramSocket();
//设置receive()方法的最长阻塞时间
socket.setSoTimeout(TIMEOUT);
DatagramPacket sendPacket=new DatagramPacket(bytesToSend,bytesToSend.length,serverAddress,servPort);
DatagramPacket receivePacket=new DatagramPacket(new byte[bytesToSend.length],bytesToSend.length);
int tries=0;
boolean receivedResponse=false;
do{
//2.使用DatagramSocket类的send()和receive()方法来发送和接收DatagramPacket实例,进行通信
socket.send(sendPacket);
try{
socket.receive(receivePacket);
if(!receivePacket.getAddress().equals(serverAddress)){
throw new IOException("Received packet from an unknown source");
}
receivedResponse=true;
}catch(InterruptedIOException e){
tries+=1;
System.out.println("Timed out,"+(MAXTRIES-tries)+" more tries ...");
}
}while(!receivedResponse&&(tries<MAXTRIES));
if(receivedResponse){
System.out.println("Received: "+new String(receivePacket.getData()));
}else{
System.out.println("No response -- giving up.");
}
//3.通信完成后,使用DatagramSocket类的close方法来销毁该套接字
socket.close();
}
}

UDP的服务器端:

Java代码  
  1. import java.io.IOException;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. public class UDPEchoServer {
  5. private static final int ECHOMAX=255;//max size of echo datagram
  6. public static void main(String[] args) throws IOException {
  7. if(args.length!=1){
  8. throw new IllegalArgumentException("Parameter(s):<Port>");
  9. }
  10. int servPort=Integer.parseInt(args[0]);
  11. //1.创建一个DatagramSocket实例,指定本地端口号,可以选择指定本地地址
  12. DatagramSocket socket=new DatagramSocket(servPort);
  13. DatagramPacket packet=new DatagramPacket(new byte[ECHOMAX],ECHOMAX);
  14. while(true){
  15. //2.使用DatagramSocket的receive方法来接收一个DatagramPacket实例。
  16. socket.receive(packet);
  17. System.out.println("Handling client at "+packet.getAddress().getHostAddress()+" on port "+packet.getPort());
  18. socket.send(packet);
  19. packet.setLength(ECHOMAX);
  20. }
  21. }
  22. }
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPEchoServer {
private static final int ECHOMAX=255;//max size of echo datagram
public static void main(String[] args) throws IOException {
if(args.length!=1){
throw new IllegalArgumentException("Parameter(s):<Port>");
}
int servPort=Integer.parseInt(args[0]);
//1.创建一个DatagramSocket实例,指定本地端口号,可以选择指定本地地址
DatagramSocket socket=new DatagramSocket(servPort);
DatagramPacket packet=new DatagramPacket(new byte[ECHOMAX],ECHOMAX);
while(true){
//2.使用DatagramSocket的receive方法来接收一个DatagramPacket实例。
socket.receive(packet);
System.out.println("Handling client at "+packet.getAddress().getHostAddress()+" on port "+packet.getPort());
socket.send(packet);
packet.setLength(ECHOMAX);
}
}
}

注意:DatagramPacket的getData()方法的使用,它返回数据缓冲区,是一个字节数组,需要注意。
  packet.setData(buf, offset,length);设置了接收数据时放到缓存去buf中的位置
,因此接收的数据new String(packet.getData(),packet.getOffset(),packet.getLength())的方式构造的。

Java TCP/IP Socket 编程 笔记(四)—发送和接收数据

  • 博客分类:
  • J2SE
编程JavaSocket
1.TCP/IP协议要求信息必须在块(chunk)中发送和接收,而块的长度必须是8位的倍数,因此,我们可以认为TCP/IP协议中传输的信息是字节序列。如何发送和解析信息需要一定的应用程序协议。
2.信息编码:
    首先是Java里对基本整型的处理,发送时,要注意:1)每种数据类型的字节个数;2)这些字节的发送顺序是怎样的?(little-endian还是big-endian);3)所传输的数值是有符号的(signed)还是无符号的(unsigned)。具体编码时采用位操作(移位和屏蔽)就可以了。具体在Java里,可以采用DataOutputStream类和ByteArrayOutputStream来实现。恢复时可以采用DataInputStream类和ByteArrayInputStream类。
    其次,字符串和文本,在一组符号与一组整数之间的映射称为编码字符集(coded character set)。发送者与接收者必须在符号与整数的映射方式上达成共识,才能使用文本信息进行通信,最简单的方法就是定义一个标准字符集。具体编码时采用String的getBytes()方法。
    最后,位操作。如果设置一个特定的设为1,先设置好掩码(mask),之后用或操作;要清空特定一位,用与操作。
3.成帧与解析
成帧(framing)技术解决了接收端如何定位消息的首位位置的问题。
如果接收者试图从套接字中读取比消息本身更多的字节,将可能发生以下两种情况之一:如果信道中没有其他消息,接收者将阻塞等待,同时无法处理接收到的消息;如果发送者也在等待接收端的响应消息,则会形成死锁(dealock);另一方面,如果信道中还有其他消息,则接收者会将后面消息的一部分甚至全部读到第一条消息中去,这将产生一些协议错误。因此,在使用TCP套接字时,成帧就是一个非常重要的考虑因素。
有两个技术:
1. 基于定界符(Delimiter-based):消息的结束由一个唯一的标记(unique marker)指出,即发送者在传输完数据后显式添加的一个特殊字节序列。这个特殊标记不能在传输的数据中出现。幸运的是,填充(stuffing)技术能够对消息中出现的定界符进行修改,从而使接收者不将其识别为定界符。在接收者扫描定界符时,还能识别出修改过的数据,并在输出消息中对其进行还原,从而使其与原始消息一致。
2. 显式长度(Explicit length):在变长字段或消息前附加一个固定大小的字段,用来指示该字段或消息中包含了多少字节。这种方法要确定消息长度的上限,以确定保存这个长度需要的字节数。
接口:

Java代码  
  1. import java.io.IOException;
  2. import java.io.OutputStream;
  3. public interface Framer {
  4. void frameMsg(byte [] message,OutputStream out) throws IOException;
  5. byte [] nextMsg() throws IOException;
  6. }
import java.io.IOException;
import java.io.OutputStream;
public interface Framer {
void frameMsg(byte [] message,OutputStream out) throws IOException;
byte [] nextMsg() throws IOException;
}

定界符的方式:

Java代码  
  1. import java.io.ByteArrayOutputStream;
  2. import java.io.EOFException;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. public class DelimFramer implements Framer {
  7. private InputStream in;//data source;
  8. private static final byte DELIMTER=(byte)'\n';//message delimiter
  9. public DelimFramer(InputStream in){
  10. this.in=in;
  11. }
  12. @Override
  13. public void frameMsg(byte[] message, OutputStream out) throws IOException {
  14. //ensure that the message dose not contain the delimiter
  15. for(byte b:message){
  16. if(b==DELIMTER)
  17. throw new IOException("Message contains delimiter");
  18. }
  19. out.write(message);
  20. out.write(DELIMTER);
  21. out.flush();
  22. }
  23. @Override
  24. public byte[] nextMsg() throws IOException {
  25. ByteArrayOutputStream messageBuffer=new ByteArrayOutputStream();
  26. int nextByte;
  27. while((nextByte=in.read())!=DELIMTER){
  28. if(nextByte==-1){//end of stream?
  29. if(messageBuffer.size()==0){
  30. return null;
  31. }else{
  32. throw new EOFException("Non-empty message without delimiter");
  33. }
  34. }
  35. messageBuffer.write(nextByte);
  36. }
  37. return messageBuffer.toByteArray();
  38. }
  39. }
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DelimFramer implements Framer {
private InputStream in;//data source;
private static final byte DELIMTER=(byte)'\n';//message delimiter
public DelimFramer(InputStream in){
this.in=in;
}
@Override
public void frameMsg(byte[] message, OutputStream out) throws IOException {
//ensure that the message dose not contain the delimiter
for(byte b:message){
if(b==DELIMTER)
throw new IOException("Message contains delimiter");
}
out.write(message);
out.write(DELIMTER);
out.flush();
}
@Override
public byte[] nextMsg() throws IOException {
ByteArrayOutputStream messageBuffer=new ByteArrayOutputStream();
int nextByte;
while((nextByte=in.read())!=DELIMTER){
if(nextByte==-1){//end of stream?
if(messageBuffer.size()==0){
return null;
}else{
throw new EOFException("Non-empty message without delimiter");
}
}
messageBuffer.write(nextByte);
}
return messageBuffer.toByteArray();
}
}

显式长度方法:

Java代码  
  1. import java.io.DataInputStream;
  2. import java.io.EOFException;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.OutputStream;
  6. public class LengthFramer implements Framer {
  7. public static final int MAXMESSAGELENGTH=65535;
  8. public static final int BYTEMASK=0xff;
  9. public static final int SHOTMASK=0xffff;
  10. public static final int BYTESHIFT=8;
  11. private DataInputStream in;// wrapper for data I/O
  12. public LengthFramer(InputStream in) throws IOException{
  13. this.in=new DataInputStream(in);
  14. }
  15. @Override
  16. public void frameMsg(byte[] message, OutputStream out) throws IOException {
  17. if(message.length>MAXMESSAGELENGTH){
  18. throw new IOException("message too long");
  19. }
  20. //write length prefix
  21. out.write((message.length>>BYTEMASK)&BYTEMASK);
  22. out.write(message.length&BYTEMASK);
  23. //write message
  24. out.write(message);
  25. out.flush();
  26. }
  27. @Override
  28. public byte[] nextMsg() throws IOException {
  29. int length;
  30. try{
  31. length=in.readUnsignedShort();
  32. }catch(EOFException e){
  33. //no (or 1 byte) message;
  34. return null;
  35. }
  36. //0<=length<=65535;
  37. byte [] msg=new byte[length];
  38. in.readFully(msg);//if exception,it's a framing error;
  39. return msg;
  40. }
  41. }

Java TCP/IP Socket 编程 笔记相关推荐

  1. Java TCP/UDP socket 编程流程总结

    最近正好学习了一点用java socket编程的东西.感觉整体的流程虽然不是很繁琐,但是也值得好好总结一下. Socket Socket可以说是一种针对网络的抽象,应用通过它可以来针对网络读写数据.就 ...

  2. 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)...

    书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子--反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 1 2 3 ...

  3. TCP IP网络编程笔记——尹圣雨

    问题: write函数 第二个参数,为什么转换成char*形式? 自己理解:char大小为1,转换成char指针,表示从第一个字节开始,第三个参数表示传递大小--字节数.与地址指针对应 传输数据时,数 ...

  4. 华为顶级网络工程师分享出这份TCP/IP网络编程笔记,已封神

    都说程序员工资高.待遇好, 2022 金九银十到了,你的小目标是 30K.40K,还是 16薪的 20K?作为一名 Java 开发工程师,当能力可以满足公司业务需求时,拿到超预期的 Offer 并不算 ...

  5. 【Java TCP/IP Socket】应用程序协议中消息的成帧与解析(含代码)

    程序间达成的某种包含了信息交换的形式和意义的共识称为协议,用来实现特定应用程序的协议叫做应用程序协议.大部分应用程序协议是根据由字段序列组成的离散信息定义的,其中每个字段中都包含了一段以位序列编码(即 ...

  6. WIFI项目--【Java TCP/IP Socket】 — 单播、广播、组播

    在当前网络通信中(TCP/IP也不例外)有三种通信模式:单播.广播.组播(又叫多播, 个人感觉叫多播描述的有点不恰当),其中多播出现的时间最晚,但同时具备单播和广播的优点,最具有发展前景. 通信方式分 ...

  7. java tcp read_【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)...

    书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子--反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 书上的服务器 ...

  8. TCP/IP 网络编程笔记 第三章 地址族与数据序列

    文章目录 3.1 分配给套接字的 IP 地址与端口号 3.1.1 网络地址(Internet Address) 3.1.2 网络地址分类与主机地址边界 3.1.3 用于区分套接字的端口号 3.2 地址 ...

  9. LwIP tcp/ip socket编程listen函数分析

    函数原型为: [cpp] view plain copy int listen(int  sockfd, int  backlog); <span style="font-family ...

最新文章

  1. 大话设计模式读后感之面向对象设计基础
  2. 【数据库】数据库基本概念:数据库管理系统 / 数据库 / 表 / 数据
  3. 劳动合同中不写薪资?
  4. 【还是回来了】博客搬家--https://cangbean.github.io
  5. 中职计算机课程教学,提高中职计算机课程教学效率的途径
  6. uva-10245-分治
  7. 【Java】Java_03第一个Java程序
  8. 关于图像高速缩放算法,目前看到的最好的最清晰的一篇文章2
  9. win7与internet时间同步出错_windows7 internet系统时间同步出错超时怎么办?国内NTP时间同步服务器地址...
  10. linux合并ts文件吗,UNIX LINUX MACOS shell 下载合并*.ts视频
  11. Java可以加速播放的播放器,基于live555的rtsp播放器之十二:使用soundtouch加速音频播放...
  12. 网络TCP/IP基础(IP地址网络汇总与规划)
  13. 内存带宽测试程序——stream2-C语言版
  14. 天津博物馆镇馆之宝——西周太保鼎
  15. 计算机科学之父——图灵
  16. 文件包含漏洞和上传漏洞
  17. 生活随记 - 尝试与师傅沟通争取自己的权益
  18. UI兼容性测试——一机多控之百度Hydra工具在移动端UI兼容性测试上的高效应用
  19. 怎么改造计算机玩游戏,大神请收下我的膝盖 牛人将红白机改造成PC玩游戏
  20. vmware虚拟服务器弊端,VM虚拟机问题总结

热门文章

  1. 基于傅里叶算子的手势识别
  2. 你不会真的以为自己懂得计算机网络吧?
  3. 多种协议数据包的结构
  4. 【Tiny4412】Tiny4412烧写uboot脚本分析
  5. 【Linux】一步一步学Linux——stat命令(77)
  6. [Qt教程] 第40篇 网络(十)WebKit初识
  7. 如何在QT中读取串口数据
  8. 使用 010 Editor 分析二进制文件格式
  9. iOS 文件预览 UIDocumentInteractionController
  10. 动态添加XtraTabControl