先描述一个场景:服务端监听8888端口,接收客户端发送来的消息,服务端打印客户端地址后,把接收到的消息原样发回客户端,客户端收到服务端发回的消息后打印出来。使用socket的TCP和UDP分别实现一个。下面看不同语言下都是怎么实现的。
C实现
TCP
tcp-server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int main()
{
int listenfd;
int connfd;
int len;
struct sockaddr_in servaddr;
struct sockaddr_in cliaddr;
int sin_size;
char buf[BUFSIZ];
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8888);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 10);
sin_size = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &sin_size);
printf("accept client %s\n", inet_ntoa(cliaddr.sin_addr));
len = recv(connfd, buf, BUFSIZ, 0);
send(connfd, buf, len, 0);
close(connfd);
close(listenfd);
return 0;
}
tcp-client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
int connfd;
int len;
struct sockaddr_in servaddr;
char buf[BUFSIZ];
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(8888);
connfd = socket(AF_INET, SOCK_STREAM, 0);
connect(connfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
send(connfd, "hello", strlen("hello"), 0);
len = recv(connfd, buf, BUFSIZ, 0);
printf("receive: %s\n", buf);
close(connfd);
return 0;
}
UDP
udp-server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main()
{
int sockfd;
int len;
struct sockaddr_in servaddr;
struct sockaddr_in cliaddr;
int sin_size;
char buf[BUFSIZ];
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8888);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
sin_size = sizeof(cliaddr);
printf("wait for a packet\n");
len = recvfrom(sockfd, buf, BUFSIZ, 0,
(struct sockaddr *)&cliaddr, &sin_size);
printf("receive packet from %s\n", inet_ntoa(cliaddr.sin_addr));
sendto(sockfd, buf, len, 0,
(struct sockaddr *)&cliaddr, sizeof(cliaddr));
close(sockfd);
return 0;
}
udp-client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
int sockfd;
int len;
struct sockaddr_in servaddr;
int sin_size;
char buf[BUFSIZ];
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(8888);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
sin_size = sizeof(servaddr);
len = sendto(sockfd, "hello", strlen("hello"), 0,
(struct sockaddr *)&servaddr, sin_size);
recvfrom(sockfd, buf, BUFSIZ, 0,
(struct sockaddr *)&servaddr, &sin_size);
printf("receive packet: %s\n", buf);
close(sockfd);
return 0;
}
Java实现
TCP
TcpServer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.net.*;
import java.io.*;
public class TcpServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept();
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip);
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
is.read(buf, 0, buf.length);
String info = new String(buf);
OutputStream os = socket.getOutputStream();
byte[] data = info.getBytes();
os.write(data, 0, data.length);
socket.close();
server.close();
}
}
TcpClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import java.net.*;
import java.io.*;
public class TcpClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream os = socket.getOutputStream();
byte[] data = "hello".getBytes();
os.write(data);
InputStream is = socket.getInputStream();
byte[] buf = new byte[1024];
is.read(buf, 0, buf.length);
String reply = new String(buf);
System.out.println(reply);
socket.close();
}
}
UDP
UdpServer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import java.net.*;
public class UdpServer {
public static void main(String[] args) throws Exception {
DatagramSocket server = new DatagramSocket(8888);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
server.receive(packet);
String info = new String(buf, 0, packet.getLength());
InetAddress address = packet.getAddress();
int port = packet.getPort();
byte[] data = info.getBytes();
packet = new DatagramPacket(data, data.length, address, port);
server.send(packet);
server.close();
}
}
UdpClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import java.net.*;
public class UdpClient {
public static void main(String[] args) throws Exception {
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 8888;
byte[] data = "hello".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
DatagramSocket client = new DatagramSocket();
client.send(packet);
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
client.receive(packet);
String reply = new String(buf, 0, packet.getLength());
System.out.println(reply);
client.close();
}
}
Python实现
TCP
tcp-server.py
1
2
3
4
5
6
7
8
9
10 import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 8888))
s.listen(8)
conn,addr = s.accept()
print addr[0]
buf = conn.recv(1024)
conn.send(buf)
conn.close()
s.close()
tcp-client.py
1
2
3
4
5
6
7 import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',8888))
s.send('hello')
data = s.recv(1024)
print data
s.close()
UDP
udp-server.py
1
2
3
4
5
6 import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('',8888))
data,addr = s.recvfrom(1024)
s.sendto(data, addr)
s.close()
udp-client.py
1
2
3
4
5
6 import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto('hello', ('127.0.0.1',8888))
data = s.recv(1024)
print data
s.close()
总结
不同语言实现相同功能,从代码量来看,肯定是python最少。为减轻工作量,有必要学习python。