socket简单实例的不同语言实现

先描述一个场景:服务端监听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
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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。