Das Verfahren ist relativ einfach, dennoch gibt es einige Dinge zu beachten:
1:int main(int argc, char **argv)
Parameter können beispielsweise beim Aufruf des Programms übergeben werden
./a.out aaa bbb ccc
Die oben genannten Parameter sind alle an die Hauptfunktion übergeben. Der formale Parameter argc in der Hauptfunktion ist die Anzahl der Parameter und **argv ist das übergebene Parameterarray (mit der Methode argv[index]). In dieser Aufgabe können Sie die IP und den Port festlegen. argv[0] ist „./a.out“ argv[1] ist „aaa“
2:perror („Socket“);
Dieser Befehl ähnelt printf, außer dass er beim Drucken die neueste Fehlermeldung ausgibt. Er kann zum Drucken von Fehlern in bestimmten Schritten (z. B. Socket-Verbindung) verwendet werden.
3:
serveraddress.sin_family= AF_INET;//ipv4
serveraddress.sin_addr.s_addr= inet_addr("0.0.0.0");//0.0.0.0是监听所有ip
serveraddress.sin_port= htons(atoi(argv[1]));//设置为大端(小端:先存储低位,大端:先存储高位)
4: gets hat einen Fehler und keine Längenbeschränkung. Sie können fgets(buf,100,stdin);// verwenden, um Tastatureingaben zu erhalten
Demonstrationsdiagramm
Klient:
/*
* @Author: CanEve
* @Date: 2023-05-12 22:52:38
* @LastEditTime: 2023-06-02 05:04:20
* @FilePath: /undefined/home/kali/cprogrames/hqyj_learn/day5/client/tcp_client.c
* @Description: 网络客户端
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv){
if(argc!=3){
printf("usage: %s <host> <port>\n",argv[0]);
return -1;
}
int socket_fd = socket(AF_INET, SOCK_STREAM,0);//使用ipv4
if(-1==socket_fd ){
perror ("socket");//可同时打印最近的报错信息
return -1;
}
struct sockaddr_in serveraddress={0};
serveraddress.sin_family= AF_INET;//ipv4
serveraddress.sin_addr.s_addr= inet_addr(/*"127.0.0.1"*/argv[1]);
serveraddress.sin_port= htons(/*8888*/atoi(argv[2]));//设置为大端(小端:先存储低位,大端:先存储高位,这里统一一下)
int conn_fd=connect(socket_fd,(struct sockaddr *)&serveraddress,sizeof(serveraddress));//连接
if(-1==conn_fd){
perror ("connect");
return -1;
}
while(1){
printf("input : ");//前部提示
fflush(stdout);//刷新缓冲区,printf需要\n刷新
//gets有bug,没有长度限制
char buf[1024];
// gets(buf);
fgets(buf,100,stdin);//获取键盘输入
write(socket_fd,buf,strlen(buf));//发送
if(read(socket_fd,buf,sizeof buf)){//接收
printf(buf);
fflush(stdout);
}
}
close(socket_fd);//关闭socket
return 0;
}
Server:
/*
* @Author: CanEve
* @Date: 2023-05-13 03:24:43
* @LastEditTime: 2023-06-02 05:32:28
* @FilePath: /day5/server/tcp_server.c
* @Description: tcp server
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include "database.h"
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv){
if(argc!=2){
printf("usage: %s <port>\n",argv[0]);
return -1;
}
// MYDATABASE db;
// database_init(&db);
// read_line("save.txt",&db);
int socket_fd = socket(AF_INET, SOCK_STREAM,0);
if(-1==socket_fd ){
perror ("socket");
return -1;
}
struct sockaddr_in serveraddress={0},clientaddr={0};
serveraddress.sin_family= AF_INET;//ipv4
serveraddress.sin_addr.s_addr= inet_addr("0.0.0.0");//0.0.0.0是监听所有ip
serveraddress.sin_port= htons(atoi(argv[1]));//设置为大端(小端:先存储低位,大端:先存储高位)
int conn_fd=bind(socket_fd,(struct sockaddr *)&serveraddress,sizeof(serveraddress));//绑定ip和端口
if(-1==conn_fd){
perror ("connect");
return -1;
}
listen(socket_fd,10);//可接受10个(但不能同时连接)
printf("Server listening on\n");
while(1){//多次连接
int client=accept(socket_fd,NULL,NULL/*(struct sockaddr *)&clientaddr,sizeof clientaddr*/);//等待客户端接入
printf("Client listening on\n");
char buf[1024];
while (1)
{
memset(buf,0,1024);
if(read(client,buf,1024)){
printf("rec -> %s\n",buf);
if(write(client,buf,strlen(buf))<=0){//返回给客户端
break;//客户端断开后等待下一个连接
}
// run_database(buf,client,&db);
}else{
break;//客户端断开后等待下一个连接
}
}
close(client);
}
close(socket_fd);
//write(client,buf,strlen(buf));
// char repeat[1024]={"hello\n"};
// write(client,repeat,6);
return 0;
}
Vollständiges Code-Repository: https://gitee.com/caneve/opencaneve/tree/main/Linux/tcp_server_client