1、socket简述
Socket是一种通信机制,通过它可以在不同主机之间进行数据交换。在Socket编程中,有两种常见的通信模式:客户端-服务器模式和点对点模式。它基于TCP/IP协议栈,并使用IP地址和端口号来标识通信的目标。
2、Socket 基于TCP开发流程
服务端
1.创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
2.绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
3.监听连接:listen(serverSocket, backlog);
4.接受连接:struct sockaddr_in clientAddress; int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));
5.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
6.关闭连接:close(clientSocket); close(serverSocket);
客服端:
1.创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
2.连接服务器:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = inet_addr(serverIP); connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
3.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
4.关闭连接:close(clientSocket);
3、Socket 基于UDP开发流程
服务端
1.创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
2.绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
3.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
4.关闭连接:close(clientSocket); close(serverSocket);
客服端:
1.创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
2.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);
3.关闭连接:close(clientSocket);
4、代码实战
1.TCP
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024
int main() {
int serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientAddrLen;
char buffer[BUFFER_SIZE];
// 创建服务端套接字
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == -1) {
perror("Failed to create socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 绑定套接字到指定地址和端口
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Failed to bind socket");
exit(EXIT_FAILURE);
}
// 监听连接请求
if (listen(serverSocket, 5) == -1) {
perror("Failed to listen");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d...\n", SERVER_PORT);
// 接受客户端连接
clientAddrLen = sizeof(clientAddr);
clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (clientSocket == -1) {
perror("Failed to accept client connection");
exit(EXIT_FAILURE);
}
printf("Client connected: %s\n", inet_ntoa(clientAddr.sin_addr));
// 接收数据
memset(buffer, 0, sizeof(buffer));
if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
perror("Failed to receive data");
exit(EXIT_FAILURE);
}
printf("Client message: %s\n", buffer);
// 发送响应
strcpy(buffer, "Hello, Client!");
if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
perror("Failed to send data");
exit(EXIT_FAILURE);
}
// 关闭套接字
close(clientSocket);
close(serverSocket);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024
int main() {
int clientSocket;
struct sockaddr_in serverAddr;
char buffer[BUFFER_SIZE];
// 创建客户端套接字
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1) {
perror("Failed to create socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT);
if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <=
0) {
perror("Failed to set server IP");
exit(EXIT_FAILURE);
}
// 连接到服务器
if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Failed to connect to server");
exit(EXIT_FAILURE);
}
printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);
// 发送数据
strcpy(buffer, "Hello, Server!");
if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
perror("Failed to send data");
exit(EXIT_FAILURE);
}
// 接收响应
memset(buffer, 0, sizeof(buffer));
if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
perror("Failed to receive data");
exit(EXIT_FAILURE);
}
printf("Server response: %s\n", buffer);
// 关闭套接字
close(clientSocket);
return 0;
}
2.UDP
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024
int main() {
int serverSocket;
struct sockaddr_in serverAddr, clientAddr;
socklen_t clientAddrLen;
char buffer[BUFFER_SIZE];
// 创建服务端套接字
serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (serverSocket == -1) {
perror("Failed to create socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 绑定套接字到指定地址和端口
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Failed to bind socket");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d...\n", SERVER_PORT);
// 接收数据
clientAddrLen = sizeof(clientAddr);
memset(buffer, 0, sizeof(buffer));
if (recvfrom(serverSocket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &clientAddrLen) == -1) {
perror("Failed to receive data");
exit(EXIT_FAILURE);
}
printf("Client message: %s\n", buffer);
// 发送响应
strcpy(buffer, "Hello, Client!");
if (sendto(serverSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&clientAddr, clientAddrLen) == -1) {
perror("Failed to send data");
exit(EXIT_FAILURE);
}
// 关闭套接字
close(serverSocket);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024
int main() {
int clientSocket;
struct sockaddr_in serverAddr;
char buffer[BUFFER_SIZE];
// 创建客户端套接字
clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (clientSocket == -1) {
perror("Failed to create socket");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVER_PORT);
if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <= 0) {
perror("Failed to set server IP");
exit(EXIT_FAILURE);
}
printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);
// 发送数据
strcpy(buffer, "Hello, Server!");
if (sendto(clientSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
perror("Failed to send data");
exit(EXIT_FAILURE);
}
// 接收响应
memset(buffer, 0, sizeof(buffer));
if (recvfrom(clientSocket, buffer, BUFFER_SIZE, 0, NULL, NULL) == -1) {
perror("Failed to receive data");
exit(EXIT_FAILURE);
}
printf("Server response: %s\n", buffer);
// 关闭套接字
close(clientSocket);
return 0;
}
3.Linux系统TCP通信实操
创建两个.c文件 socket_server.c 和 socket_client.c(名字可以自己取)
不会vi编译器的直接使用最简单的gedit操作,把代码复制进去 save.
现在创建好两个文件,可以进行gcc编译,生成两个可执行文件。
打开两个cmd 窗口,首先运行socket_server,再运行socket_client就可以通信成功。
最后说一下TCP 和UDP 代码是不同的,TCP是面向可靠的连接传输,UDP是面向不可靠的,所以TCP连接要复杂一点。
如有侵权,请联系删除。