普通socket编程
TCP服务器端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int server_sockfd;//服务器端套接字
int client_sockfd;//客户端套接字
int len;
struct sockaddr_in my_addr; //服务器网络地址结构体
struct sockaddr_in remote_addr; //客户端网络地址结构体
int sin_size;
char buf[BUFSIZ]; //数据传送的缓冲区
memset(&my_addr,0,sizeof(my_addr)); //数据初始化--清零
my_addr.sin_family=AF_INET; //设置为IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上
my_addr.sin_port=htons(8000); //服务器端口号
/*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
return 1;
}
/*将套接字绑定到服务器的网络地址上*/
if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
perror("bind");
return 1;
}
/*监听连接请求--监听队列长度为5*/
listen(server_sockfd,5);
sin_size=sizeof(struct sockaddr_in);
/*等待客户端连接请求到达*/
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
{
perror("accept");
return 1;
}
printf("accept client %s/n",inet_ntoa(remote_addr.sin_addr));
len=send(client_sockfd,"Welcome to my server/n",21,0);//发送欢迎信息
/*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/
while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))
{
buf[len]='/0';
printf("%s/n",buf);
if(send(client_sockfd,buf,len,0)<0)
{
perror("write");
return 1;
}
}
close(client_sockfd);
close(server_sockfd);
return 0;
}
TCP客户端编程(socket_comunication_client.c)
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr; //服务器端网络地址结构体
char buf[BUFSIZ]; //数据传送的缓冲区
memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零
remote_addr.sin_family=AF_INET; //设置为IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址
remote_addr.sin_port=htons(8000); //服务器端口号
/*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
return 1;
}
/*将套接字绑定到服务器的网络地址上*/
if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
{
perror("connect");
return 1;
}
printf("connected to server/n");
len=recv(client_sockfd,buf,BUFSIZ,0);//接收服务器端信息
buf[len]='/0';
printf("%s",buf); //打印服务器端信息
/*循环的发送接收信息并打印接收信息--recv返回接收到的字节数,send返回发送的字节数*/
while(1)
{
printf("Enter string to send:");
scanf("%s",buf);
if(!strcmp(buf,"quit")
break;
len=send(client_sockfd,buf,strlen(buf),0);
len=recv(client_sockfd,buf,BUFSIZ,0);
buf[len]='/0';
printf("received:%s/n",buf);
}
close(client_sockfd);//关闭套接字
return 0;
}
以上代码转载自linux socket编程
Openssl AES加密
-
首先安装openssl和相关库(Ubuntu)
apt-get install openssl libssl-dev
- 编写相关加密解密代码
- aes_options.h
#ifndef _ASE_H_
#define _ASE_H_
int encrypt(char *input_string, char **encrypt_string);
void decrypt(char *encrypt_string, char **decrypt_string, int len);
#endif
- aes_options.c
#include <stdio.h>
#include <openssl/aes.h>
#include <stdlib.h>
#include <string.h>
int encrypt(char *input_string, char **encrypt_string)
{
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
unsigned char iv[AES_BLOCK_SIZE]; // init vector
unsigned int len; // encrypt length (in multiple of AES_BLOCK_SIZE)
unsigned int i;
// set the encryption length
len = 0;
if ((strlen(input_string) + 1) % AES_BLOCK_SIZE == 0)
{
len = strlen(input_string) + 1;
}
else
{
len = ((strlen(input_string) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
}
// Generate AES 128-bit key
for (i=0; i<16; ++i) {
key[i] = 32 + i;
}
// Set encryption key
for (i=0; i<AES_BLOCK_SIZE; ++i) {
iv[i] = 0;
}
if (AES_set_encrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set encryption key in AES\n");
exit(0);
}
// alloc encrypt_string
*encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (*encrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
exit(-1);
}
// encrypt (iv will change)
AES_cbc_encrypt(input_string, *encrypt_string, len, &aes, iv, AES_ENCRYPT);
return len;
}
void decrypt(char *encrypt_string, char **decrypt_string,int len)
{
unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
unsigned char iv[AES_BLOCK_SIZE]; // init vector
AES_KEY aes;
int i;
// Generate AES 128-bit key
for (i=0; i<16; ++i) {
key[i] = 32 + i;
}
// alloc decrypt_string
*decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (*decrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
exit(-1);
}
// Set decryption key
for (i=0; i<AES_BLOCK_SIZE; ++i) {
iv[i] = 0;
}
if (AES_set_decrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set decryption key in AES\n");
exit(-1);
}
// decrypt
AES_cbc_encrypt(encrypt_string, *decrypt_string, len, &aes, iv,
AES_DECRYPT);
}
修改普通socket的代码
在修改地方加上了 //add
或者modified
注释
服务器端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h" //add
int main()
{
int server_fd;
int client_fd;
int len;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
char buffer[BUFSIZ];
// printf("%d",BUFSIZ);
memset(&server_addr, 0, sizeof(server_addr)); //initialize struct
memset(&server_addr, 0, sizeof(client_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(9000);
if((server_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) //create server socket
{
perror("socket create failed");
return 1;
}
if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) //bind info on server socket
{
perror("bind failed");
return 1;
}
listen(server_fd, 5); //listen port 9000
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) < 0)
{
perror("accept failed");
return 1;
}
printf("accept client %s\n", inet_ntoa(client_addr.sin_addr));
len = send(client_fd, "Welcome to my server\n", 21, 0);
while((len=recv(client_fd, buffer, BUFSIZ, 0)) > 0)
{
char *decryto_string = NULL; //add
decrypt(buffer, &decryto_string, len); //add
printf("%s \n", decryto_string);
if(send(client_fd, decryto_string, len, 0) < 0) //modified
{
perror("send failed");
return 1;
}
}
close(client_fd);
close(server_fd);
return 0;
}
客户端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h" //add
int main()
{
int len;
int client_sockfd;
struct sockaddr_in server_addr;
char buffer[BUFSIZ];
char *encrypt_string = NULL;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(9000);
if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket create failed");
return 1;
}
if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
{
perror("connect failed");
return 1;
}
printf("connect to server\n");
len = recv(client_sockfd, buffer, BUFSIZ, 0);
buffer[len] = '\0';
printf("%s", buffer);
while(1)
{
printf("enter a data:");
scanf("%s", buffer);
if(!strcmp(buffer,"quit"))
break;
int encrypt_length = encrypt(buffer, &encrypt_string); //add
len = send(client_sockfd, encrypt_string, encrypt_length, 0); //add
len = recv(client_sockfd, buffer, BUFSIZ, 0);
buffer[len] = '\0';
printf("recived:%s \n", buffer);
}
close(client_sockfd);
printf("bye");
return 0;
}
解释说明
- 文件
aes_options.h
和aes_options.c
里面为两个函数,第一个为加密,第二个为解密. - 在socket的两个文件中引入
aes_options.h
即可使用两个函数.. - 编译的时候需要执行如下命令:
gcc aes_options.c socket_comunication_server.c -o server -lcrypto
gcc aes_options.c socket_comunication_client.c -o client -lcrypto## 标题文字 ##
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。