add all
This commit is contained in:
parent
f1c858469d
commit
d5eba67d09
8
Clion/.idea/.gitignore
vendored
Normal file
8
Clion/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
2
Clion/.idea/Clion.iml
Normal file
2
Clion/.idea/Clion.iml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
251
Clion/.idea/editor.xml
Normal file
251
Clion/.idea/editor.xml
Normal file
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BackendCodeEditorSettings">
|
||||
<option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Component_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Component Designer generated code" type="string" />
|
||||
<option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Designer_0020generated_0020code/@EntryIndexedValue" value="Designer generated code" type="string" />
|
||||
<option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Web_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Web Form Designer generated code" type="string" />
|
||||
<option name="/Default/CodeInspection/GeneratedCode/GeneratedCodeRegions/=Windows_0020Form_0020Designer_0020generated_0020code/@EntryIndexedValue" value="Windows Form Designer generated code" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedOverridenMethod/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantFwdClassOrEnumSpecifier/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifierADL/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
|
||||
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
|
||||
</component>
|
||||
</project>
|
8
Clion/.idea/misc.xml
Normal file
8
Clion/.idea/misc.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakePythonSetting">
|
||||
<option name="pythonIntegrationState" value="YES" />
|
||||
</component>
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
<component name="WestSettings">{}</component>
|
||||
</project>
|
8
Clion/.idea/modules.xml
Normal file
8
Clion/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Clion.iml" filepath="$PROJECT_DIR$/.idea/Clion.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
Clion/.idea/vcs.xml
Normal file
6
Clion/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
6
Clion/CMakeLists.txt
Normal file
6
Clion/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.31)
|
||||
project(Clion C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
add_executable(Clion main.c)
|
7
Clion/main.c
Normal file
7
Clion/main.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
10
Clion/test.c
Normal file
10
Clion/test.c
Normal file
@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by ZBright on 25-5-29.
|
||||
//
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hello World\n");
|
||||
return 0;
|
||||
}
|
BIN
Clion/test.exe
Normal file
BIN
Clion/test.exe
Normal file
Binary file not shown.
0
Code/Project_Client.c
Normal file
0
Code/Project_Client.c
Normal file
0
Code/Project_Server.c
Normal file
0
Code/Project_Server.c
Normal file
54
Code/cet.c
Normal file
54
Code/cet.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include<stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>/* See NOTES */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define OWNADDR "192.168.0.17" //我自己电脑的ip地址
|
||||
#define OWNPORT 10000 //我自己电脑的该程序的端口号
|
||||
|
||||
#define SERVERADDR "192.168.0.114" //对方的服务器的IP地址
|
||||
#define SERVERPORT 20000 //对方的服务器的端口号
|
||||
|
||||
int main()
|
||||
{
|
||||
//1、买手机(建立套接字)
|
||||
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(socketfd == -1)
|
||||
{
|
||||
printf("没钱了....,失败\n");
|
||||
return -1;
|
||||
}
|
||||
//2、绑定自己的电话号码(绑定自己的IP地址 和端口号)
|
||||
//定义一个IPV4结构体变量,初始化自己的IP地址和端口号
|
||||
struct sockaddr_in ownAddr;
|
||||
ownAddr.sin_family = AF_INET;/*地址族 IPV4*/
|
||||
ownAddr.sin_port = htons(OWNPORT);//htons 将本地端口号转为网络端口号
|
||||
ownAddr.sin_addr.s_addr = inet_addr(OWNADDR);//将本地IP地址转为网络IP地址
|
||||
|
||||
bind(socketfd, (struct sockaddr *)&ownAddr,sizeof(struct sockaddr_in));
|
||||
|
||||
//3、开始打电话(发起连接)
|
||||
struct sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;/*地址族 IPV4*/
|
||||
serverAddr.sin_port = htons(SERVERPORT); //htons 将本地端口号转为网络端口号
|
||||
serverAddr.sin_addr.s_addr = inet_addr(SERVERADDR); //将本地IP地址转为网络IP地址
|
||||
|
||||
connect(socketfd,(struct sockaddr *)&serverAddr,sizeof(struct sockaddr_in));
|
||||
|
||||
//4、聊天
|
||||
while(1)
|
||||
{
|
||||
printf("data:");
|
||||
char buf[1024]={0};
|
||||
scanf("%s",buf);
|
||||
//发送数据
|
||||
send(socketfd, buf, strlen(buf), 0);
|
||||
}
|
||||
//5、关闭
|
||||
close(socketfd);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
Code/output/cet
Normal file
BIN
Code/output/cet
Normal file
Binary file not shown.
65
Code/ser.c
Normal file
65
Code/ser.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include<stdio.h>
|
||||
#include <sys/types.h> /* See NOTES */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include<stdlib.h>
|
||||
|
||||
|
||||
|
||||
#define SERVER_ADDR "172.29.147.16" //服务器的IP地址
|
||||
#define SERVER_PORT 20000 //port 服务器的端口号
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int ret;
|
||||
//1、买手机(建立套接字)
|
||||
int socketFd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(socketFd == -1){
|
||||
perror("socket error");
|
||||
exit(0);
|
||||
}
|
||||
//2、绑定自己的电话号码(绑定自己的IP地址和端口号)
|
||||
//定义一个IPV4结构体变量,存储IP地址和端口号
|
||||
struct sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET ;//IPv4
|
||||
serverAddr.sin_port = htons(SERVER_PORT);//16端口号 --本地端口号--网络端口号
|
||||
serverAddr.sin_addr.s_addr = inet_addr(SERVER_ADDR); //32IP地址 --本地IP--网络IP
|
||||
|
||||
ret = bind(socketFd, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr_in));
|
||||
if(ret == -1){
|
||||
perror("bind error");
|
||||
exit(0);
|
||||
}
|
||||
//3、设置铃声(设置监听)
|
||||
ret = listen(socketFd, 20); //20表示同时连接上来的客户端的最大数量
|
||||
if(ret == -1){
|
||||
perror("listen error");
|
||||
exit(0);
|
||||
}
|
||||
printf("阻塞等待新的客户端连接......\n");
|
||||
//4、坐等电话(阻塞等待客户端的连接)
|
||||
int newClientFd = accept(socketFd, NULL,NULL);
|
||||
if(ret == -1){
|
||||
perror("accept error");
|
||||
exit(0);
|
||||
}
|
||||
//注意 accept函数的返回值 表示 新的客户端的文件描述符 ,后面与客户端通信 必须使用该文件描述符
|
||||
printf("有新的客户端连接上来....\n");
|
||||
|
||||
//5、聊天 接收 数据
|
||||
while(1)
|
||||
{
|
||||
char buf[1024]={0};
|
||||
read(newClientFd,buf,sizeof(buf));
|
||||
printf("buf:%s\n",buf);
|
||||
}
|
||||
|
||||
//6、关闭 断开连接
|
||||
close(socketFd);
|
||||
close(newClientFd);
|
||||
|
||||
return 0;
|
||||
}
|
BIN
Project/client
Normal file
BIN
Project/client
Normal file
Binary file not shown.
270
Project/client.c
Normal file
270
Project/client.c
Normal file
@ -0,0 +1,270 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
#define SERVER_IP "127.0.0.1"
|
||||
#define PORT 8888
|
||||
|
||||
int client_socket;
|
||||
pthread_t receive_thread;
|
||||
int running = 1;
|
||||
|
||||
// 函数声明
|
||||
void *receive_messages(void *arg);
|
||||
void handle_signal(int sig);
|
||||
void login_register_menu();
|
||||
|
||||
int main() {
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
// 创建socket
|
||||
client_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (client_socket == -1) {
|
||||
perror("Socket creation failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 准备服务器地址
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(PORT);
|
||||
|
||||
// 将IPv4地址从点分十进制转换为二进制形式
|
||||
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
|
||||
perror("Invalid address/ Address not supported");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 连接到服务器
|
||||
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||||
perror("Connection failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Connected to server.\n");
|
||||
|
||||
// 设置信号处理
|
||||
signal(SIGINT, handle_signal);
|
||||
|
||||
// 创建接收消息的线程
|
||||
if (pthread_create(&receive_thread, NULL, receive_messages, NULL) != 0) {
|
||||
perror("Thread creation failed");
|
||||
close(client_socket);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 登录/注册菜单
|
||||
login_register_menu();
|
||||
|
||||
// 聊天循环
|
||||
printf("\nWelcome to the chat! Type /help for commands.\n");
|
||||
char message[BUFFER_SIZE];
|
||||
while (running) {
|
||||
memset(message, 0, BUFFER_SIZE);
|
||||
fgets(message, BUFFER_SIZE - 1, stdin);
|
||||
|
||||
// 移除换行符
|
||||
size_t len = strlen(message);
|
||||
if (len > 0 && message[len - 1] == '\n') {
|
||||
message[len - 1] = '\0';
|
||||
}
|
||||
|
||||
// 检查是否是退出命令
|
||||
if (strcmp(message, "/quit") == 0) {
|
||||
running = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// 发送消息到服务器
|
||||
if (send(client_socket, message, strlen(message), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 等待接收线程结束
|
||||
pthread_join(receive_thread, NULL);
|
||||
|
||||
// 关闭socket
|
||||
close(client_socket);
|
||||
printf("Disconnected from server.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *receive_messages(void *arg) {
|
||||
char buffer[BUFFER_SIZE];
|
||||
int bytes_received;
|
||||
|
||||
while (running) {
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client_socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
|
||||
if (bytes_received <= 0) {
|
||||
// 服务器断开连接
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// 打印接收到的消息
|
||||
printf("%s", buffer);
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void handle_signal(int sig) {
|
||||
printf("\nExiting...\n");
|
||||
running = 0;
|
||||
close(client_socket);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void login_register_menu() {
|
||||
char buffer[BUFFER_SIZE];
|
||||
int choice;
|
||||
char username[BUFFER_SIZE];
|
||||
char password[BUFFER_SIZE];
|
||||
|
||||
while (running) {
|
||||
// 接收菜单
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 发送选择
|
||||
scanf("%d", &choice);
|
||||
getchar(); // 消耗换行符
|
||||
sprintf(buffer, "%d", choice);
|
||||
if (send(client_socket, buffer, strlen(buffer), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理登录
|
||||
if (choice == 1) {
|
||||
// 接收用户名提示
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 发送用户名
|
||||
fgets(username, BUFFER_SIZE - 1, stdin);
|
||||
username[strcspn(username, "\n")] = 0; // 移除换行符
|
||||
if (send(client_socket, username, strlen(username), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 接收密码提示
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 发送密码
|
||||
fgets(password, BUFFER_SIZE - 1, stdin);
|
||||
password[strcspn(password, "\n")] = 0; // 移除换行符
|
||||
if (send(client_socket, password, strlen(password), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 接收登录结果
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 检查是否登录成功
|
||||
if (strstr(buffer, "Login successful") != NULL) {
|
||||
// 接收帮助信息
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) > 0) {
|
||||
printf("%s", buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 处理注册
|
||||
else if (choice == 2) {
|
||||
// 接收用户名提示
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 发送用户名
|
||||
fgets(username, BUFFER_SIZE - 1, stdin);
|
||||
username[strcspn(username, "\n")] = 0; // 移除换行符
|
||||
if (send(client_socket, username, strlen(username), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 接收密码提示
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
|
||||
// 发送密码
|
||||
fgets(password, BUFFER_SIZE - 1, stdin);
|
||||
password[strcspn(password, "\n")] = 0; // 移除换行符
|
||||
if (send(client_socket, password, strlen(password), 0) == -1) {
|
||||
perror("Send failed");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 接收注册结果
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
}
|
||||
else {
|
||||
// 接收无效选择提示
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
if (recv(client_socket, buffer, BUFFER_SIZE - 1, 0) <= 0) {
|
||||
printf("Server disconnected.\n");
|
||||
running = 0;
|
||||
return;
|
||||
}
|
||||
printf("%s", buffer);
|
||||
}
|
||||
}
|
||||
}
|
BIN
Project/server
Normal file
BIN
Project/server
Normal file
Binary file not shown.
471
Project/server.c
Normal file
471
Project/server.c
Normal file
@ -0,0 +1,471 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define MAX_CLIENTS 10
|
||||
#define BUFFER_SIZE 1024
|
||||
#define USERNAME_LENGTH 50
|
||||
#define PASSWORD_LENGTH 50
|
||||
#define FILENAME "./users.txt"
|
||||
|
||||
typedef struct {
|
||||
int socket;
|
||||
char username[USERNAME_LENGTH];
|
||||
pthread_t thread;
|
||||
int active;
|
||||
} Client;
|
||||
|
||||
Client clients[MAX_CLIENTS];
|
||||
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
int server_socket;
|
||||
|
||||
// 函数声明
|
||||
void handle_signal(int sig);
|
||||
void *handle_client(void *arg);
|
||||
int find_client_index(int socket);
|
||||
int find_client_index_by_username(const char *username);
|
||||
void send_private_message(const char *sender, const char *recipient, const char *message);
|
||||
void list_users(int client_socket);
|
||||
int authenticate_user(const char *username, const char *password);
|
||||
int register_user(const char *username, const char *password);
|
||||
void save_user(const char *username, const char *password);
|
||||
|
||||
int main() {
|
||||
int client_socket;
|
||||
struct sockaddr_in server_addr, client_addr;
|
||||
socklen_t client_addr_len = sizeof(client_addr);
|
||||
|
||||
// 创建socket
|
||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_socket == -1) {
|
||||
perror("Socket creation failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 设置socket选项
|
||||
int opt = 1;
|
||||
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
|
||||
perror("Setsockopt failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 准备服务器地址
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
server_addr.sin_port = htons(8888);
|
||||
|
||||
// 绑定socket
|
||||
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
|
||||
perror("Bind failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 监听连接
|
||||
if (listen(server_socket, 5) == -1) {
|
||||
perror("Listen failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Server started. Waiting for connections...\n");
|
||||
|
||||
// 初始化客户端数组
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
clients[i].socket = -1;
|
||||
clients[i].active = 0;
|
||||
}
|
||||
|
||||
// 设置信号处理
|
||||
signal(SIGINT, handle_signal);
|
||||
|
||||
// 接受客户端连接
|
||||
while (1) {
|
||||
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
|
||||
if (client_socket == -1) {
|
||||
perror("Accept failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 查找空闲位置
|
||||
int i;
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].socket == -1) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
clients[i].socket = client_socket;
|
||||
clients[i].active = 1;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
// 创建线程处理客户端
|
||||
if (pthread_create(&clients[i].thread, NULL, handle_client, &clients[i]) != 0) {
|
||||
perror("Thread creation failed");
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
clients[i].socket = -1;
|
||||
clients[i].active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client_socket);
|
||||
}
|
||||
pthread_detach(clients[i].thread);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == MAX_CLIENTS) {
|
||||
// 服务器已满
|
||||
char response[] = "Server is full. Try again later.\n";
|
||||
send(client_socket, response, strlen(response), 0);
|
||||
close(client_socket);
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭服务器socket
|
||||
close(server_socket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handle_signal(int sig) {
|
||||
printf("\nShutting down server...\n");
|
||||
|
||||
// 关闭所有客户端socket
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].socket != -1) {
|
||||
close(clients[i].socket);
|
||||
clients[i].socket = -1;
|
||||
clients[i].active = 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
// 关闭服务器socket
|
||||
close(server_socket);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void *handle_client(void *arg) {
|
||||
Client *client = (Client *)arg;
|
||||
char buffer[BUFFER_SIZE];
|
||||
int bytes_received;
|
||||
|
||||
// 登录/注册流程
|
||||
while (1) {
|
||||
// 发送菜单
|
||||
char menu[] = "1. Login\n2. Register\nEnter choice: ";
|
||||
send(client->socket, menu, strlen(menu), 0);
|
||||
|
||||
// 接收选择
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client->socket);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int choice = atoi(buffer);
|
||||
|
||||
// 处理登录
|
||||
if (choice == 1) {
|
||||
// 请求用户名
|
||||
char username_prompt[] = "Username: ";
|
||||
send(client->socket, username_prompt, strlen(username_prompt), 0);
|
||||
|
||||
// 接收用户名
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client->socket);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
char username[USERNAME_LENGTH];
|
||||
strncpy(username, buffer, USERNAME_LENGTH - 1);
|
||||
|
||||
// 请求密码
|
||||
char password_prompt[] = "Password: ";
|
||||
send(client->socket, password_prompt, strlen(password_prompt), 0);
|
||||
|
||||
// 接收密码
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client->socket);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
char password[PASSWORD_LENGTH];
|
||||
strncpy(password, buffer, PASSWORD_LENGTH - 1);
|
||||
|
||||
// 验证用户
|
||||
if (authenticate_user(username, password)) {
|
||||
// 检查用户名是否已被使用
|
||||
int username_in_use = 0;
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (i != find_client_index(client->socket) && clients[i].active &&
|
||||
strcmp(clients[i].username, username) == 0) {
|
||||
username_in_use = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
if (username_in_use) {
|
||||
char response[] = "Username already in use. Please try again.\n";
|
||||
send(client->socket, response, strlen(response), 0);
|
||||
} else {
|
||||
// 登录成功
|
||||
strcpy(client->username, username);
|
||||
char success[] = "Login successful. Welcome to the chat!\n";
|
||||
send(client->socket, success, strlen(success), 0);
|
||||
|
||||
// 通知用户可用命令
|
||||
char help[] = "Available commands:\n/private <username> <message> - Send private message\n/list - List online users\n/quit - Exit chat\n";
|
||||
send(client->socket, help, strlen(help), 0);
|
||||
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
char response[] = "Authentication failed. Please try again.\n";
|
||||
send(client->socket, response, strlen(response), 0);
|
||||
}
|
||||
}
|
||||
// 处理注册
|
||||
else if (choice == 2) {
|
||||
// 请求用户名
|
||||
char username_prompt[] = "Enter username: ";
|
||||
send(client->socket, username_prompt, strlen(username_prompt), 0);
|
||||
|
||||
// 接收用户名
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client->socket);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
char username[USERNAME_LENGTH];
|
||||
strncpy(username, buffer, USERNAME_LENGTH - 1);
|
||||
|
||||
// 请求密码
|
||||
char password_prompt[] = "Enter password: ";
|
||||
send(client->socket, password_prompt, strlen(password_prompt), 0);
|
||||
|
||||
// 接收密码
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
close(client->socket);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
char password[PASSWORD_LENGTH];
|
||||
strncpy(password, buffer, PASSWORD_LENGTH - 1);
|
||||
|
||||
// 注册用户
|
||||
if (register_user(username, password)) {
|
||||
char success[] = "Registration successful. You can now login.\n";
|
||||
send(client->socket, success, strlen(success), 0);
|
||||
} else {
|
||||
char response[] = "Registration failed. Username already exists.\n";
|
||||
send(client->socket, response, strlen(response), 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
char response[] = "Invalid choice. Please try again.\n";
|
||||
send(client->socket, response, strlen(response), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 聊天循环
|
||||
while (1) {
|
||||
memset(buffer, 0, BUFFER_SIZE);
|
||||
bytes_received = recv(client->socket, buffer, BUFFER_SIZE - 1, 0);
|
||||
|
||||
if (bytes_received <= 0) {
|
||||
// 客户端断开连接
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查是否是退出命令
|
||||
if (strncmp(buffer, "/quit", 5) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查是否是列出用户命令
|
||||
if (strncmp(buffer, "/list", 5) == 0) {
|
||||
list_users(client->socket);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查是否是私聊命令
|
||||
if (strncmp(buffer, "/private", 7) == 0) {
|
||||
char recipient[USERNAME_LENGTH];
|
||||
char message[BUFFER_SIZE - USERNAME_LENGTH - 8];
|
||||
|
||||
// 解析命令
|
||||
sscanf(buffer, "/private %s %[^\n]", recipient, message);
|
||||
|
||||
// 发送私聊消息
|
||||
send_private_message(client->username, recipient, message);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 发送帮助信息
|
||||
char help[] = "Invalid command. Available commands:\n/private <username> <message> - Send private message\n/list - List online users\n/quit - Exit chat\n";
|
||||
send(client->socket, help, strlen(help), 0);
|
||||
}
|
||||
|
||||
// 客户端断开连接
|
||||
char leave_message[BUFFER_SIZE];
|
||||
snprintf(leave_message, BUFFER_SIZE, "%s has left the chat.\n", client->username);
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (i != find_client_index(client->socket) && clients[i].active) {
|
||||
send(clients[i].socket, leave_message, strlen(leave_message), 0);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
// 关闭客户端socket
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
close(client->socket);
|
||||
client->socket = -1;
|
||||
client->active = 0;
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int find_client_index(int socket) {
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].socket == socket) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_client_index_by_username(const char *username) {
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].active && strcmp(clients[i].username, username) == 0) {
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void send_private_message(const char *sender, const char *recipient, const char *message) {
|
||||
int recipient_index = find_client_index_by_username(recipient);
|
||||
|
||||
if (recipient_index == -1) {
|
||||
char error[BUFFER_SIZE];
|
||||
snprintf(error, BUFFER_SIZE, "Error: User '%s' not found or offline.\n", recipient);
|
||||
|
||||
int sender_index = find_client_index_by_username(sender);
|
||||
if (sender_index != -1) {
|
||||
send(clients[sender_index].socket, error, strlen(error), 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 发送消息给接收者
|
||||
char private_message[BUFFER_SIZE];
|
||||
snprintf(private_message, BUFFER_SIZE, "[Private from %s]: %s\n", sender, message);
|
||||
send(clients[recipient_index].socket, private_message, strlen(private_message), 0);
|
||||
|
||||
// 发送确认给发送者
|
||||
char confirmation[BUFFER_SIZE];
|
||||
snprintf(confirmation, BUFFER_SIZE, "[Private to %s]: %s\n", recipient, message);
|
||||
int sender_index = find_client_index_by_username(sender);
|
||||
if (sender_index != -1) {
|
||||
send(clients[sender_index].socket, confirmation, strlen(confirmation), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void list_users(int client_socket) {
|
||||
char response[BUFFER_SIZE] = "Online users:\n";
|
||||
|
||||
pthread_mutex_lock(&clients_mutex);
|
||||
for (int i = 0; i < MAX_CLIENTS; i++) {
|
||||
if (clients[i].active) {
|
||||
strncat(response, clients[i].username, USERNAME_LENGTH - strlen(response) - 2);
|
||||
strcat(response, "\n");
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&clients_mutex);
|
||||
|
||||
send(client_socket, response, strlen(response), 0);
|
||||
}
|
||||
|
||||
int authenticate_user(const char *username, const char *password) {
|
||||
FILE *file = fopen(FILENAME, "r");
|
||||
if (file == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char stored_username[USERNAME_LENGTH];
|
||||
char stored_password[PASSWORD_LENGTH];
|
||||
int found = 0;
|
||||
|
||||
while (fscanf(file, "%s %s", stored_username, stored_password) != EOF) {
|
||||
if (strcmp(username, stored_username) == 0 && strcmp(password, stored_password) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return found;
|
||||
}
|
||||
|
||||
int register_user(const char *username, const char *password) {
|
||||
FILE *file = fopen(FILENAME, "r");
|
||||
if (file == NULL) {
|
||||
file = fopen(FILENAME, "w");
|
||||
if (file == NULL) {
|
||||
return 0;
|
||||
}
|
||||
fclose(file);
|
||||
file = fopen(FILENAME, "r");
|
||||
}
|
||||
|
||||
char stored_username[USERNAME_LENGTH];
|
||||
while (fscanf(file, "%s", stored_username) != EOF) {
|
||||
if (strcmp(username, stored_username) == 0) {
|
||||
fclose(file);
|
||||
return 0; // 用户名已存在
|
||||
}
|
||||
// 跳过密码
|
||||
fscanf(file, "%*s");
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
// 添加新用户
|
||||
save_user(username, password);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void save_user(const char *username, const char *password) {
|
||||
FILE *file = fopen(FILENAME, "a");
|
||||
if (file != NULL) {
|
||||
fprintf(file, "%s %s\n", username, password);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
422
Project/test/Client.c
Normal file
422
Project/test/Client.c
Normal file
@ -0,0 +1,422 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MAX_BUFFER 1024
|
||||
#define PORT 8888
|
||||
#define SERVER_IP "127.0.0.1"
|
||||
#define MAX_FRIENDS 50
|
||||
|
||||
// 好友结构体
|
||||
typedef struct {
|
||||
char username[50];
|
||||
int index;
|
||||
} Friend;
|
||||
|
||||
// 全局变量
|
||||
int client_socket;
|
||||
int current_user_index = -1;
|
||||
char current_username[50];
|
||||
pthread_t receive_thread;
|
||||
Friend friends[MAX_FRIENDS];
|
||||
int friend_count = 0;
|
||||
|
||||
// 函数声明
|
||||
void connect_to_server();
|
||||
void* receive_messages(void* arg);
|
||||
void show_login_menu();
|
||||
void show_main_menu();
|
||||
void login();
|
||||
void register_user();
|
||||
void add_friend();
|
||||
void remove_friend();
|
||||
void chat_with_friend();
|
||||
void logout();
|
||||
void get_friends_list();
|
||||
void display_friends_list();
|
||||
|
||||
int main() {
|
||||
connect_to_server();
|
||||
show_login_menu();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void connect_to_server() {
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
// 创建socket
|
||||
client_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (client_socket < 0) {
|
||||
perror("创建Socket失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 设置服务器地址
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(PORT);
|
||||
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
|
||||
|
||||
// 连接服务器
|
||||
if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
|
||||
perror("连接服务器失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("成功连接到服务器!\n");
|
||||
// 不要在这里启动接收线程
|
||||
}
|
||||
|
||||
void* receive_messages(void* arg) {
|
||||
char buffer[MAX_BUFFER];
|
||||
while (1) {
|
||||
memset(buffer, 0, MAX_BUFFER);
|
||||
if (recv(client_socket, buffer, MAX_BUFFER, 0) <= 0) {
|
||||
printf("\n连接已断开\n");
|
||||
current_user_index = -1;
|
||||
close(client_socket);
|
||||
connect_to_server();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 处理PING消息
|
||||
if (strcmp(buffer, "PING") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理好友列表消息
|
||||
if (strncmp(buffer, "FRIENDLIST", 10) == 0) {
|
||||
friend_count = 0; // 重置好友计数
|
||||
char* token = strtok(buffer + 11, " ");
|
||||
while (token != NULL && friend_count < MAX_FRIENDS) {
|
||||
char* comma = strchr(token, ',');
|
||||
if (comma != NULL) {
|
||||
*comma = '\0';
|
||||
strncpy(friends[friend_count].username, token, sizeof(friends[friend_count].username)-1);
|
||||
friends[friend_count].username[sizeof(friends[friend_count].username)-1] = '\0';
|
||||
friends[friend_count].index = atoi(comma + 1);
|
||||
friend_count++;
|
||||
}
|
||||
token = strtok(NULL, " ");
|
||||
}
|
||||
printf("\n好友列表已更新\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理好友操作响应
|
||||
if (strncmp(buffer, "FRIEND_ADD_SUCCESS", 17) == 0 ||
|
||||
strncmp(buffer, "FRIEND_REMOVE_SUCCESS", 20) == 0) {
|
||||
printf("\n%s\n", buffer);
|
||||
get_friends_list();
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理聊天消息
|
||||
if (strncmp(buffer, "CHAT", 4) == 0) {
|
||||
printf("\n%s\n", buffer + 5);
|
||||
}
|
||||
// 处理系统消息
|
||||
else if (strncmp(buffer, "系统消息", 8) == 0 ||
|
||||
strncmp(buffer, "FRIEND_", 7) == 0) {
|
||||
printf("\n%s\n", buffer);
|
||||
}
|
||||
// 处理其他消息
|
||||
else {
|
||||
printf("\n%s\n", buffer);
|
||||
}
|
||||
|
||||
if (current_user_index != -1) {
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void show_login_menu() {
|
||||
int choice;
|
||||
while (1) {
|
||||
printf("\n=== 登录菜单 ===\n");
|
||||
printf("1. 登录\n");
|
||||
printf("2. 注册\n");
|
||||
printf("3. 退出\n");
|
||||
printf("请选择: ");
|
||||
scanf("%d", &choice);
|
||||
getchar(); // 清除输入缓冲
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
login();
|
||||
break;
|
||||
case 2:
|
||||
register_user();
|
||||
break;
|
||||
case 3:
|
||||
logout(); // 确保在退出前发送登出消息
|
||||
close(client_socket);
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
printf("无效选择\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void show_main_menu() {
|
||||
int choice;
|
||||
while (current_user_index != -1) { // 只在用户已登录时显示菜单
|
||||
printf("\n=== 主菜单 ===\n");
|
||||
printf("1. 添加好友\n");
|
||||
printf("2. 删除好友\n");
|
||||
printf("3. 与好友聊天\n");
|
||||
printf("4. 查看好友列表\n");
|
||||
printf("5. 退出登录\n");
|
||||
printf("6. 退出程序\n");
|
||||
printf("请选择: ");
|
||||
|
||||
if (scanf("%d", &choice) != 1) {
|
||||
// 清除输入缓冲
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && c != EOF);
|
||||
printf("无效输入,请重新选择\n");
|
||||
continue;
|
||||
}
|
||||
getchar(); // 清除输入缓冲
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
add_friend();
|
||||
break;
|
||||
case 2:
|
||||
remove_friend();
|
||||
break;
|
||||
case 3:
|
||||
chat_with_friend();
|
||||
break;
|
||||
case 4:
|
||||
get_friends_list();
|
||||
display_friends_list();
|
||||
break;
|
||||
case 5:
|
||||
logout();
|
||||
return;
|
||||
case 6:
|
||||
logout();
|
||||
close(client_socket);
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
printf("无效选择\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void login() {
|
||||
char username[50], password[50];
|
||||
char buffer[MAX_BUFFER];
|
||||
char response[MAX_BUFFER];
|
||||
|
||||
printf("用户名: ");
|
||||
scanf("%s", username);
|
||||
printf("密码: ");
|
||||
scanf("%s", password);
|
||||
getchar(); // 清除输入缓冲
|
||||
|
||||
snprintf(buffer, MAX_BUFFER, "LOGIN %s %s", username, password);
|
||||
send(client_socket, buffer, MAX_BUFFER, 0);
|
||||
|
||||
// 等待服务器响应
|
||||
memset(response, 0, MAX_BUFFER);
|
||||
if (recv(client_socket, response, MAX_BUFFER, 0) <= 0) {
|
||||
printf("登录失败:连接已断开\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp(response, "SUCCESS", 7) == 0) {
|
||||
sscanf(response, "SUCCESS %d", ¤t_user_index);
|
||||
strncpy(current_username, username, sizeof(current_username) - 1);
|
||||
current_username[sizeof(current_username) - 1] = '\0';
|
||||
printf("登录成功!\n");
|
||||
// 登录成功后再启动接收线程
|
||||
if (pthread_create(&receive_thread, NULL, receive_messages, NULL) != 0) {
|
||||
perror("创建线程失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
get_friends_list();
|
||||
show_main_menu();
|
||||
} else {
|
||||
printf("登录失败: %s\n", response + 5);
|
||||
}
|
||||
}
|
||||
|
||||
void register_user() {
|
||||
char username[50], password[50];
|
||||
char buffer[MAX_BUFFER];
|
||||
|
||||
printf("用户名: ");
|
||||
scanf("%s", username);
|
||||
printf("密码: ");
|
||||
scanf("%s", password);
|
||||
|
||||
snprintf(buffer, MAX_BUFFER, "REGISTER %s %s", username, password);
|
||||
send(client_socket, buffer, MAX_BUFFER, 0);
|
||||
|
||||
// 等待服务器响应
|
||||
memset(buffer, 0, MAX_BUFFER);
|
||||
recv(client_socket, buffer, MAX_BUFFER, 0);
|
||||
|
||||
if (strcmp(buffer, "SUCCESS") == 0) {
|
||||
printf("注册成功!\n");
|
||||
} else {
|
||||
printf("注册失败: %s\n", buffer + 5);
|
||||
}
|
||||
}
|
||||
|
||||
void get_friends_list() {
|
||||
char buffer[MAX_BUFFER];
|
||||
snprintf(buffer, MAX_BUFFER, "GETFRIENDS %d", current_user_index);
|
||||
send(client_socket, buffer, MAX_BUFFER, 0);
|
||||
// 等待接收线程处理好友列表
|
||||
usleep(100000); // 等待100ms
|
||||
}
|
||||
|
||||
void display_friends_list() {
|
||||
printf("\n=== 好友列表 ===\n");
|
||||
if (friend_count == 0) {
|
||||
printf("暂无好友\n");
|
||||
} else {
|
||||
for (int i = 0; i < friend_count; i++) {
|
||||
printf("%d. %s\n", i + 1, friends[i].username);
|
||||
}
|
||||
}
|
||||
printf("----------------\n");
|
||||
}
|
||||
|
||||
void chat_with_friend() {
|
||||
char buffer[MAX_BUFFER];
|
||||
char message[MAX_BUFFER];
|
||||
int choice;
|
||||
|
||||
get_friends_list();
|
||||
if (friend_count == 0) {
|
||||
printf("您还没有好友,请先添加好友!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
display_friends_list();
|
||||
printf("请选择要聊天的好友编号: ");
|
||||
scanf("%d", &choice);
|
||||
getchar(); // 清除输入缓冲
|
||||
|
||||
if (choice < 1 || choice > friend_count) {
|
||||
printf("无效的选择!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int friend_index = friends[choice - 1].index;
|
||||
printf("\n开始与 %s 聊天(输入'exit'退出):\n", friends[choice - 1].username);
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
|
||||
while (1) {
|
||||
fgets(message, sizeof(message), stdin);
|
||||
message[strcspn(message, "\n")] = 0; // 移除换行符
|
||||
// 限制 message 长度
|
||||
message[sizeof(message)-1] = '\0';
|
||||
if (strcmp(message, "exit") == 0) {
|
||||
break;
|
||||
}
|
||||
int n = snprintf(buffer, MAX_BUFFER, "CHAT %d %d %s", current_user_index, friend_index, message);
|
||||
if (n < 0 || n >= MAX_BUFFER) {
|
||||
strcpy(&buffer[MAX_BUFFER-5], "...");
|
||||
}
|
||||
send(client_socket, buffer, MAX_BUFFER, 0);
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void add_friend() {
|
||||
char friend_name[50];
|
||||
char buffer[MAX_BUFFER];
|
||||
|
||||
printf("请输入要添加的好友用户名: ");
|
||||
if (scanf("%49s", friend_name) != 1) {
|
||||
getchar();
|
||||
printf("输入无效\n");
|
||||
return;
|
||||
}
|
||||
getchar();
|
||||
|
||||
snprintf(buffer, MAX_BUFFER, "ADDFRIEND %d %s", current_user_index, friend_name);
|
||||
|
||||
// 设置发送超时
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof tv);
|
||||
|
||||
if (send(client_socket, buffer, MAX_BUFFER, 0) <= 0) {
|
||||
printf("发送请求失败\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("添加好友请求已发送,等待服务器响应...\n");
|
||||
}
|
||||
|
||||
void remove_friend() {
|
||||
char buffer[MAX_BUFFER];
|
||||
|
||||
get_friends_list();
|
||||
usleep(100000); // 等待好友列表更新
|
||||
|
||||
if (friend_count == 0) {
|
||||
printf("您还没有好友!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
display_friends_list();
|
||||
printf("请输入要删除的好友编号: ");
|
||||
int choice;
|
||||
if (scanf("%d", &choice) != 1) {
|
||||
getchar();
|
||||
printf("输入无效!\n");
|
||||
return;
|
||||
}
|
||||
getchar();
|
||||
|
||||
if (choice < 1 || choice > friend_count) {
|
||||
printf("无效的选择!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置发送超时
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(client_socket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof tv);
|
||||
|
||||
snprintf(buffer, MAX_BUFFER, "REMOVEFRIEND %d %s",
|
||||
current_user_index,
|
||||
friends[choice - 1].username);
|
||||
|
||||
if (send(client_socket, buffer, MAX_BUFFER, 0) <= 0) {
|
||||
printf("发送请求失败\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("删除好友请求已发送,等待服务器响应...\n");
|
||||
}
|
||||
|
||||
void logout() {
|
||||
if (current_user_index != -1) {
|
||||
char buffer[MAX_BUFFER];
|
||||
snprintf(buffer, MAX_BUFFER, "LOGOUT");
|
||||
send(client_socket, buffer, MAX_BUFFER, 0);
|
||||
current_user_index = -1;
|
||||
printf("已退出登录\n");
|
||||
}
|
||||
}
|
517
Project/test/Server.c
Normal file
517
Project/test/Server.c
Normal file
@ -0,0 +1,517 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#define MAX_BUFFER 1024
|
||||
#define MAX_USERS 100
|
||||
#define MAX_FRIENDS 50
|
||||
#define PORT 8888
|
||||
|
||||
// 用户结构体
|
||||
typedef struct {
|
||||
char username[50];
|
||||
char password[50];
|
||||
int friends[MAX_FRIENDS];
|
||||
int friend_count;
|
||||
int online;
|
||||
int socket; // 添加socket字段
|
||||
} User;
|
||||
|
||||
// 全局变量
|
||||
User users[MAX_USERS];
|
||||
int user_count = 0;
|
||||
pthread_mutex_t users_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// 函数声明
|
||||
void load_users();
|
||||
void save_users();
|
||||
int find_user(const char* username);
|
||||
void* handle_client(void* arg);
|
||||
void process_login(int client_socket, char* buffer);
|
||||
void process_register(int client_socket, char* buffer);
|
||||
void process_add_friend(int client_socket, char* buffer);
|
||||
void process_remove_friend(int client_socket, char* buffer);
|
||||
void process_chat(int client_socket, char* buffer);
|
||||
void display_online_users(); // 新增函数声明
|
||||
void process_get_friends(int client_socket, char* buffer);
|
||||
|
||||
int main() {
|
||||
int server_socket, client_socket;
|
||||
struct sockaddr_in server_addr, client_addr;
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
pthread_t thread_id;
|
||||
|
||||
// 加载用户数据
|
||||
load_users();
|
||||
|
||||
// 创建socket
|
||||
server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_socket < 0) {
|
||||
perror("创建Socket失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 设置服务器地址
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
server_addr.sin_port = htons(PORT);
|
||||
|
||||
// 绑定socket
|
||||
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
|
||||
perror("绑定失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// 监听连接
|
||||
if (listen(server_socket, 5) < 0) {
|
||||
perror("监听失败");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("服务器已启动,监听端口 %d\n", PORT);
|
||||
|
||||
// 接受客户端连接
|
||||
while (1) {
|
||||
client_socket = accept(server_socket, (struct sockaddr*)&client_addr, &client_len);
|
||||
if (client_socket < 0) {
|
||||
perror("接受连接失败");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("新客户端连接:%s:%d\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
|
||||
|
||||
// 为每个客户端创建新线程
|
||||
if (pthread_create(&thread_id, NULL, handle_client, (void*)&client_socket) != 0) {
|
||||
perror("创建线程失败");
|
||||
close(client_socket);
|
||||
}
|
||||
}
|
||||
|
||||
close(server_socket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_users() {
|
||||
FILE* file = fopen("Users.txt", "r");
|
||||
if (file == NULL) {
|
||||
printf("未找到用户文件,将创建新文件。\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (fscanf(file, "%s %s %d", users[user_count].username,
|
||||
users[user_count].password, &users[user_count].friend_count) == 3) {
|
||||
for (int i = 0; i < users[user_count].friend_count; i++) {
|
||||
fscanf(file, "%d", &users[user_count].friends[i]);
|
||||
}
|
||||
users[user_count].online = 0;
|
||||
users[user_count].socket = -1;
|
||||
user_count++;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
void save_users() {
|
||||
FILE* file = fopen("Users.txt", "w");
|
||||
if (file == NULL) {
|
||||
perror("无法打开用户文件");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
fprintf(file, "%s %s %d", users[i].username,
|
||||
users[i].password, users[i].friend_count);
|
||||
for (int j = 0; j < users[i].friend_count; j++) {
|
||||
fprintf(file, " %d", users[i].friends[j]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
int find_user(const char* username) {
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (strcmp(users[i].username, username) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* handle_client(void* arg) {
|
||||
int client_socket = *((int*)arg);
|
||||
char buffer[MAX_BUFFER];
|
||||
int user_index = -1;
|
||||
|
||||
// 设置socket选项,启用保活机制
|
||||
int keepalive = 1;
|
||||
int keepidle = 5; // 5秒没有数据交互就开始探测
|
||||
int keepinterval = 2; // 探测间隔2秒
|
||||
int keepcount = 3; // 探测3次无响应就断开
|
||||
|
||||
setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive));
|
||||
setsockopt(client_socket, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
|
||||
setsockopt(client_socket, IPPROTO_TCP, TCP_KEEPINTVL, &keepinterval, sizeof(keepinterval));
|
||||
setsockopt(client_socket, IPPROTO_TCP, TCP_KEEPCNT, &keepcount, sizeof(keepcount));
|
||||
|
||||
while (1) {
|
||||
memset(buffer, 0, MAX_BUFFER);
|
||||
int bytes_received = recv(client_socket, buffer, MAX_BUFFER, 0);
|
||||
|
||||
// 检查连接状态
|
||||
if (bytes_received <= 0) {
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
// 查找并更新断开连接的用户状态
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (users[i].socket == client_socket) {
|
||||
user_index = i;
|
||||
users[i].online = 0;
|
||||
users[i].socket = -1;
|
||||
printf("\n用户 %s 断开连接\n", users[i].username);
|
||||
|
||||
// 通知所有在线好友
|
||||
for (int j = 0; j < users[i].friend_count; j++) {
|
||||
int friend_index = users[i].friends[j];
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
char notify[MAX_BUFFER];
|
||||
sprintf(notify, "系统消息: 您的好友 %s 已离线", users[i].username);
|
||||
send(users[friend_index].socket, notify, MAX_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
save_users();
|
||||
display_online_users();
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
char command[20];
|
||||
sscanf(buffer, "%s", command);
|
||||
|
||||
if (strcmp(command, "LOGIN") == 0) {
|
||||
process_login(client_socket, buffer);
|
||||
// 更新user_index
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (users[i].socket == client_socket) {
|
||||
user_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(command, "REGISTER") == 0) {
|
||||
process_register(client_socket, buffer);
|
||||
}
|
||||
else if (strcmp(command, "ADDFRIEND") == 0) {
|
||||
process_add_friend(client_socket, buffer);
|
||||
}
|
||||
else if (strcmp(command, "REMOVEFRIEND") == 0) {
|
||||
process_remove_friend(client_socket, buffer);
|
||||
}
|
||||
else if (strcmp(command, "CHAT") == 0) {
|
||||
process_chat(client_socket, buffer);
|
||||
}
|
||||
else if (strcmp(command, "LOGOUT") == 0) {
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
// 查找当前用户
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (users[i].socket == client_socket) {
|
||||
user_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (user_index != -1) {
|
||||
users[user_index].online = 0;
|
||||
users[user_index].socket = -1;
|
||||
// 通知所有在线好友
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
int friend_index = users[user_index].friends[i];
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
char notify[MAX_BUFFER];
|
||||
sprintf(notify, "系统消息: 您的好友 %s 已离线", users[user_index].username);
|
||||
send(users[friend_index].socket, notify, MAX_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
save_users();
|
||||
printf("\n用户 %s 退出登录\n", users[user_index].username);
|
||||
display_online_users();
|
||||
}
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
break;
|
||||
}
|
||||
else if (strcmp(command, "GETFRIENDS") == 0) {
|
||||
process_get_friends(client_socket, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// 确保在断开连接时清理用户状态
|
||||
if (user_index != -1) {
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
users[user_index].online = 0;
|
||||
users[user_index].socket = -1;
|
||||
save_users();
|
||||
display_online_users();
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
close(client_socket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void process_login(int client_socket, char* buffer) {
|
||||
char username[50], password[50];
|
||||
sscanf(buffer, "LOGIN %s %s", username, password);
|
||||
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
int user_index = find_user(username);
|
||||
|
||||
if (user_index == -1) {
|
||||
send(client_socket, "FAIL 用户不存在", MAX_BUFFER, 0);
|
||||
}
|
||||
else if (strcmp(users[user_index].password, password) != 0) {
|
||||
send(client_socket, "FAIL 密码错误", MAX_BUFFER, 0);
|
||||
}
|
||||
else {
|
||||
// 如果用户已经在线,先将其标记为离线
|
||||
if (users[user_index].online) {
|
||||
users[user_index].online = 0;
|
||||
users[user_index].socket = -1;
|
||||
}
|
||||
|
||||
// 更新用户状态
|
||||
users[user_index].online = 1;
|
||||
users[user_index].socket = client_socket;
|
||||
save_users();
|
||||
|
||||
char response[MAX_BUFFER];
|
||||
snprintf(response, MAX_BUFFER, "SUCCESS %d", user_index);
|
||||
send(client_socket, response, MAX_BUFFER, 0);
|
||||
printf("\n用户 %s 登录成功\n", username);
|
||||
|
||||
// 通知所有在线好友
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
int friend_index = users[user_index].friends[i];
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
char notify[MAX_BUFFER];
|
||||
snprintf(notify, MAX_BUFFER, "系统消息: 您的好友 %s 已上线", username);
|
||||
send(users[friend_index].socket, notify, MAX_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
display_online_users();
|
||||
}
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
void process_register(int client_socket, char* buffer) {
|
||||
char username[50], password[50];
|
||||
sscanf(buffer, "REGISTER %s %s", username, password);
|
||||
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
if (find_user(username) != -1) {
|
||||
send(client_socket, "FAIL 用户名已存在", MAX_BUFFER, 0);
|
||||
}
|
||||
else if (user_count >= MAX_USERS) {
|
||||
send(client_socket, "FAIL 用户数量已达上限", MAX_BUFFER, 0);
|
||||
}
|
||||
else {
|
||||
strcpy(users[user_count].username, username);
|
||||
strcpy(users[user_count].password, password);
|
||||
users[user_count].friend_count = 0;
|
||||
users[user_count].online = 0;
|
||||
users[user_count].socket = -1;
|
||||
user_count++;
|
||||
save_users();
|
||||
send(client_socket, "SUCCESS", MAX_BUFFER, 0);
|
||||
}
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
void process_add_friend(int client_socket, char* buffer) {
|
||||
int user_index;
|
||||
char friend_name[50];
|
||||
sscanf(buffer, "ADDFRIEND %d %s", &user_index, friend_name);
|
||||
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
int friend_index = find_user(friend_name);
|
||||
|
||||
if (friend_index == -1) {
|
||||
send(client_socket, "FAIL 好友不存在", MAX_BUFFER, 0);
|
||||
}
|
||||
else if (user_index == friend_index) {
|
||||
send(client_socket, "FAIL 不能添加自己为好友", MAX_BUFFER, 0);
|
||||
}
|
||||
else {
|
||||
// 检查是否已经是好友
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
if (users[user_index].friends[i] == friend_index) {
|
||||
send(client_socket, "FAIL 已经是好友关系", MAX_BUFFER, 0);
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加好友
|
||||
users[user_index].friends[users[user_index].friend_count++] = friend_index;
|
||||
users[friend_index].friends[users[friend_index].friend_count++] = user_index;
|
||||
save_users();
|
||||
send(client_socket, "SUCCESS", MAX_BUFFER, 0);
|
||||
|
||||
// 通知被添加的用户
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
char notify[MAX_BUFFER];
|
||||
snprintf(notify, MAX_BUFFER, "系统消息: %s 添加您为好友", users[user_index].username);
|
||||
send(users[friend_index].socket, notify, MAX_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
void process_remove_friend(int client_socket, char* buffer) {
|
||||
int user_index;
|
||||
char friend_name[50];
|
||||
sscanf(buffer, "REMOVEFRIEND %d %s", &user_index, friend_name);
|
||||
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
int friend_index = find_user(friend_name);
|
||||
|
||||
if (friend_index == -1) {
|
||||
send(client_socket, "FAIL 好友不存在", MAX_BUFFER, 0);
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
// 从用户的好友列表中移除
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
if (users[user_index].friends[i] == friend_index) {
|
||||
for (int j = i; j < users[user_index].friend_count - 1; j++) {
|
||||
users[user_index].friends[j] = users[user_index].friends[j + 1];
|
||||
}
|
||||
users[user_index].friend_count--;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
// 从好友的好友列表中移除
|
||||
for (int i = 0; i < users[friend_index].friend_count; i++) {
|
||||
if (users[friend_index].friends[i] == user_index) {
|
||||
for (int j = i; j < users[friend_index].friend_count - 1; j++) {
|
||||
users[friend_index].friends[j] = users[friend_index].friends[j + 1];
|
||||
}
|
||||
users[friend_index].friend_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
save_users();
|
||||
|
||||
// 发送成功响应
|
||||
send(client_socket, "FRIEND_REMOVE_SUCCESS", MAX_BUFFER, 0);
|
||||
|
||||
// 发送通知给被删除的好友
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
char notify[MAX_BUFFER];
|
||||
snprintf(notify, MAX_BUFFER, "FRIEND_REMOVE %s 将您从好友列表中移除",
|
||||
users[user_index].username);
|
||||
send(users[friend_index].socket, notify, MAX_BUFFER, 0);
|
||||
}
|
||||
} else {
|
||||
send(client_socket, "FAIL 不是好友关系", MAX_BUFFER, 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
void process_chat(int client_socket, char* buffer) {
|
||||
int user_index, friend_index;
|
||||
char message[MAX_BUFFER];
|
||||
sscanf(buffer, "CHAT %d %d %[^\n]", &user_index, &friend_index, message);
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
// 验证是否是好友关系
|
||||
int is_friend = 0;
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
if (users[user_index].friends[i] == friend_index) {
|
||||
is_friend = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_friend) {
|
||||
send(client_socket, "FAIL 不是好友关系", MAX_BUFFER, 0);
|
||||
}
|
||||
else {
|
||||
char response[MAX_BUFFER];
|
||||
// 限制 message 长度,防止溢出
|
||||
char safe_message[MAX_BUFFER/2];
|
||||
strncpy(safe_message, message, sizeof(safe_message) - 1);
|
||||
safe_message[sizeof(safe_message) - 1] = '\0';
|
||||
int n = snprintf(response, MAX_BUFFER, "CHAT %s: %s", users[user_index].username, safe_message);
|
||||
if (n < 0 || n >= MAX_BUFFER) {
|
||||
// 被截断,补上 ...
|
||||
strcpy(&response[MAX_BUFFER-5], "...");
|
||||
}
|
||||
// 发送给发送者
|
||||
send(client_socket, response, MAX_BUFFER, 0);
|
||||
// 发送给接收者
|
||||
if (users[friend_index].online && users[friend_index].socket != -1) {
|
||||
send(users[friend_index].socket, response, MAX_BUFFER, 0);
|
||||
} else {
|
||||
// 好友不在线,给发送者提示
|
||||
send(client_socket, "系统消息: 对方不在线,消息未送达", MAX_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
||||
|
||||
// 新增函数:显示在线用户
|
||||
void display_online_users() {
|
||||
printf("\n当前在线用户:\n");
|
||||
int online_count = 0;
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (users[i].online) {
|
||||
printf("%d. %s\n", ++online_count, users[i].username);
|
||||
}
|
||||
}
|
||||
if (online_count == 0) {
|
||||
printf("暂无在线用户\n");
|
||||
}
|
||||
printf("------------------------\n");
|
||||
}
|
||||
|
||||
// 新增函数:处理获取好友列表请求
|
||||
void process_get_friends(int client_socket, char* buffer) {
|
||||
int user_index;
|
||||
sscanf(buffer, "GETFRIENDS %d", &user_index);
|
||||
|
||||
pthread_mutex_lock(&users_mutex);
|
||||
char response[MAX_BUFFER] = "FRIENDLIST ";
|
||||
char temp[64];
|
||||
|
||||
for (int i = 0; i < users[user_index].friend_count; i++) {
|
||||
int friend_index = users[user_index].friends[i];
|
||||
int n = snprintf(temp, sizeof(temp), "%s,%d ", users[friend_index].username, friend_index);
|
||||
if (n < 0 || n >= sizeof(temp)) {
|
||||
strcpy(&temp[sizeof(temp)-5], "...");
|
||||
}
|
||||
if (strlen(response) + strlen(temp) < MAX_BUFFER) {
|
||||
strcat(response, temp);
|
||||
} else {
|
||||
strcat(response, "...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
send(client_socket, response, MAX_BUFFER, 0);
|
||||
pthread_mutex_unlock(&users_mutex);
|
||||
}
|
BIN
Project/test/client
Normal file
BIN
Project/test/client
Normal file
Binary file not shown.
BIN
Project/test/server
Normal file
BIN
Project/test/server
Normal file
Binary file not shown.
1
Project/users.txt
Normal file
1
Project/users.txt
Normal file
@ -0,0 +1 @@
|
||||
test password
|
108
Project/新建文件夹/Client_Cursor.c
Normal file
108
Project/新建文件夹/Client_Cursor.c
Normal file
@ -0,0 +1,108 @@
|
||||
// client.c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include "protocol.h"
|
||||
|
||||
#define SERVER_IP "127.0.0.1"
|
||||
#define PORT 8888
|
||||
|
||||
int sockfd;
|
||||
char username[MAX_NAME_LEN];
|
||||
|
||||
// 接收消息线程
|
||||
void *recv_thread(void *arg) {
|
||||
Message msg;
|
||||
while (1) {
|
||||
int n = recv(sockfd, &msg, sizeof(msg), 0);
|
||||
if (n <= 0) break;
|
||||
if (msg.type == MSG_PRIVATE_CHAT) {
|
||||
printf("\n[私聊]%s: %s\n", msg.from, msg.data);
|
||||
printf(">> ");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void menu() {
|
||||
printf("1. 注册\n2. 登录\n选择: ");
|
||||
}
|
||||
|
||||
void chat_menu() {
|
||||
printf("1. 添加好友\n2. 私聊\n3. 退出\n选择: ");
|
||||
}
|
||||
|
||||
int main() {
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in servaddr = {0};
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORT);
|
||||
inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr);
|
||||
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
|
||||
int choice;
|
||||
Message msg, reply;
|
||||
while (1) {
|
||||
menu();
|
||||
scanf("%d", &choice);
|
||||
getchar();
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
if (choice == 1) {
|
||||
msg.type = MSG_REGISTER;
|
||||
printf("用户名: "); fgets(msg.from, MAX_NAME_LEN, stdin); msg.from[strcspn(msg.from, "\n")] = 0;
|
||||
printf("密码: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||||
send(sockfd, &msg, sizeof(msg), 0);
|
||||
recv(sockfd, &reply, sizeof(reply), 0);
|
||||
if (reply.type == MSG_OK) printf("注册成功\n");
|
||||
else printf("注册失败: %s\n", reply.data);
|
||||
} else if (choice == 2) {
|
||||
msg.type = MSG_LOGIN;
|
||||
printf("用户名: "); fgets(msg.from, MAX_NAME_LEN, stdin); msg.from[strcspn(msg.from, "\n")] = 0;
|
||||
printf("密码: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||||
send(sockfd, &msg, sizeof(msg), 0);
|
||||
recv(sockfd, &reply, sizeof(reply), 0);
|
||||
if (reply.type == MSG_OK) {
|
||||
strcpy(username, msg.from);
|
||||
printf("登录成功\n");
|
||||
break;
|
||||
} else {
|
||||
printf("登录失败: %s\n", reply.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, recv_thread, NULL);
|
||||
|
||||
while (1) {
|
||||
chat_menu();
|
||||
scanf("%d", &choice);
|
||||
getchar();
|
||||
if (choice == 1) {
|
||||
msg.type = MSG_ADD_FRIEND;
|
||||
strcpy(msg.from, username);
|
||||
printf("好友用户名: "); fgets(msg.to, MAX_NAME_LEN, stdin); msg.to[strcspn(msg.to, "\n")] = 0;
|
||||
send(sockfd, &msg, sizeof(msg), 0);
|
||||
recv(sockfd, &reply, sizeof(reply), 0);
|
||||
if (reply.type == MSG_OK) printf("添加好友成功\n");
|
||||
else printf("添加失败: %s\n", reply.data);
|
||||
} else if (choice == 2) {
|
||||
msg.type = MSG_PRIVATE_CHAT;
|
||||
strcpy(msg.from, username);
|
||||
printf("好友用户名: "); fgets(msg.to, MAX_NAME_LEN, stdin); msg.to[strcspn(msg.to, "\n")] = 0;
|
||||
printf("消息内容: "); fgets(msg.data, MAX_MSG_LEN, stdin); msg.data[strcspn(msg.data, "\n")] = 0;
|
||||
send(sockfd, &msg, sizeof(msg), 0);
|
||||
recv(sockfd, &reply, sizeof(reply), 0);
|
||||
if (reply.type == MSG_OK) printf("消息已发送\n");
|
||||
else printf("发送失败: %s\n", reply.data);
|
||||
} else if (choice == 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(sockfd);
|
||||
return 0;
|
||||
}
|
138
Project/新建文件夹/Server_Cursor.c
Normal file
138
Project/新建文件夹/Server_Cursor.c
Normal file
@ -0,0 +1,138 @@
|
||||
// server.c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include "protocol.h"
|
||||
#include "user.h"
|
||||
|
||||
#define PORT 8888
|
||||
#define MAX_USERS 100
|
||||
#define MAX_CLIENTS 100
|
||||
|
||||
typedef struct {
|
||||
int sockfd;
|
||||
char username[MAX_NAME_LEN];
|
||||
} Client;
|
||||
|
||||
User users[MAX_USERS];
|
||||
int user_count = 0;
|
||||
Client clients[MAX_CLIENTS];
|
||||
int client_count = 0;
|
||||
pthread_mutex_t user_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// 查找在线客户端
|
||||
int find_client(const char *username) {
|
||||
for (int i = 0; i < client_count; i++) {
|
||||
if (strcmp(clients[i].username, username) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 处理客户端请求
|
||||
void *client_handler(void *arg) {
|
||||
int sockfd = *(int *)arg;
|
||||
char curr_user[MAX_NAME_LEN] = "";
|
||||
Message msg, reply;
|
||||
while (1) {
|
||||
int n = recv(sockfd, &msg, sizeof(msg), 0);
|
||||
if (n <= 0) break;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
switch (msg.type) {
|
||||
case MSG_REGISTER:
|
||||
pthread_mutex_lock(&user_mutex);
|
||||
if (add_user(users, &user_count, msg.from, msg.data)) {
|
||||
save_users(users, user_count);
|
||||
reply.type = MSG_OK;
|
||||
} else {
|
||||
reply.type = MSG_FAIL;
|
||||
strcpy(reply.data, "用户名已存在");
|
||||
}
|
||||
pthread_mutex_unlock(&user_mutex);
|
||||
send(sockfd, &reply, sizeof(reply), 0);
|
||||
break;
|
||||
case MSG_LOGIN:
|
||||
pthread_mutex_lock(&user_mutex);
|
||||
if (check_password(users, user_count, msg.from, msg.data)) {
|
||||
strcpy(curr_user, msg.from);
|
||||
pthread_mutex_lock(&client_mutex);
|
||||
strcpy(clients[client_count].username, curr_user);
|
||||
clients[client_count++].sockfd = sockfd;
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
reply.type = MSG_OK;
|
||||
} else {
|
||||
reply.type = MSG_FAIL;
|
||||
strcpy(reply.data, "用户名或密码错误");
|
||||
}
|
||||
pthread_mutex_unlock(&user_mutex);
|
||||
send(sockfd, &reply, sizeof(reply), 0);
|
||||
break;
|
||||
case MSG_ADD_FRIEND:
|
||||
pthread_mutex_lock(&user_mutex);
|
||||
if (add_friend(users, user_count, curr_user, msg.to)) {
|
||||
save_users(users, user_count);
|
||||
reply.type = MSG_OK;
|
||||
} else {
|
||||
reply.type = MSG_FAIL;
|
||||
strcpy(reply.data, "添加好友失败");
|
||||
}
|
||||
pthread_mutex_unlock(&user_mutex);
|
||||
send(sockfd, &reply, sizeof(reply), 0);
|
||||
break;
|
||||
case MSG_PRIVATE_CHAT:
|
||||
pthread_mutex_lock(&client_mutex);
|
||||
int idx = find_client(msg.to);
|
||||
if (idx != -1) {
|
||||
send(clients[idx].sockfd, &msg, sizeof(msg), 0);
|
||||
reply.type = MSG_OK;
|
||||
} else {
|
||||
reply.type = MSG_FAIL;
|
||||
strcpy(reply.data, "对方不在线");
|
||||
}
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
send(sockfd, &reply, sizeof(reply), 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 客户端断开,移除
|
||||
pthread_mutex_lock(&client_mutex);
|
||||
for (int i = 0; i < client_count; i++) {
|
||||
if (clients[i].sockfd == sockfd) {
|
||||
clients[i] = clients[--client_count];
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&client_mutex);
|
||||
close(sockfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in servaddr = {0};
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
servaddr.sin_port = htons(PORT);
|
||||
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
listen(listenfd, 5);
|
||||
|
||||
user_count = load_users(users, MAX_USERS);
|
||||
printf("服务器启动,监听端口%d\n", PORT);
|
||||
|
||||
while (1) {
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, client_handler, &connfd);
|
||||
pthread_detach(tid);
|
||||
}
|
||||
close(listenfd);
|
||||
return 0;
|
||||
}
|
94
Project/新建文件夹/User.c
Normal file
94
Project/新建文件夹/User.c
Normal file
@ -0,0 +1,94 @@
|
||||
// user.c
|
||||
#include "user.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define USER_FILE "users.txt"
|
||||
#define MAX_LINE 256
|
||||
|
||||
// 加载所有用户
|
||||
int load_users(User users[], int max_users) {
|
||||
FILE *fp = fopen(USER_FILE, "r");
|
||||
if (!fp) return 0;
|
||||
int count = 0;
|
||||
char line[MAX_LINE];
|
||||
while (fgets(line, sizeof(line), fp) && count < max_users) {
|
||||
User *u = &users[count];
|
||||
char *p = strtok(line, " \n");
|
||||
if (!p) continue;
|
||||
strcpy(u->username, p);
|
||||
p = strtok(NULL, " \n");
|
||||
if (!p) continue;
|
||||
strcpy(u->password, p);
|
||||
u->friend_count = 0;
|
||||
p = strtok(NULL, " \n");
|
||||
if (p) {
|
||||
char *f = strtok(p, ",");
|
||||
while (f && u->friend_count < MAX_FRIENDS) {
|
||||
strcpy(u->friends[u->friend_count++], f);
|
||||
f = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
fclose(fp);
|
||||
return count;
|
||||
}
|
||||
|
||||
// 保存所有用户
|
||||
int save_users(User users[], int user_count) {
|
||||
FILE *fp = fopen(USER_FILE, "w");
|
||||
if (!fp) return -1;
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
fprintf(fp, "%s %s", users[i].username, users[i].password);
|
||||
for (int j = 0; j < users[i].friend_count; j++) {
|
||||
fprintf(fp, "%c%s", j == 0 ? ' ' : ',', users[i].friends[j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
int find_user(User users[], int user_count, const char *username) {
|
||||
for (int i = 0; i < user_count; i++) {
|
||||
if (strcmp(users[i].username, username) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查密码
|
||||
int check_password(User users[], int user_count, const char *username, const char *password) {
|
||||
int idx = find_user(users, user_count, username);
|
||||
if (idx == -1) return 0;
|
||||
return strcmp(users[idx].password, password) == 0;
|
||||
}
|
||||
|
||||
// 添加用户
|
||||
int add_user(User users[], int *user_count, const char *username, const char *password) {
|
||||
if (find_user(users, *user_count, username) != -1) return 0;
|
||||
User *u = &users[(*user_count)++];
|
||||
strcpy(u->username, username);
|
||||
strcpy(u->password, password);
|
||||
u->friend_count = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 添加好友
|
||||
int add_friend(User users[], int user_count, const char *username, const char *friendname) {
|
||||
int idx = find_user(users, user_count, username);
|
||||
int fidx = find_user(users, user_count, friendname);
|
||||
if (idx == -1 || fidx == -1) return 0;
|
||||
User *u = &users[idx];
|
||||
for (int i = 0; i < u->friend_count; i++) {
|
||||
if (strcmp(u->friends[i], friendname) == 0)
|
||||
return 0; // 已是好友
|
||||
}
|
||||
if (u->friend_count < MAX_FRIENDS) {
|
||||
strcpy(u->friends[u->friend_count++], friendname);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
21
Project/新建文件夹/User.h
Normal file
21
Project/新建文件夹/User.h
Normal file
@ -0,0 +1,21 @@
|
||||
// user.h
|
||||
#ifndef USER_H
|
||||
#define USER_H
|
||||
|
||||
#define MAX_FRIENDS 10
|
||||
|
||||
typedef struct {
|
||||
char username[32];
|
||||
char password[32];
|
||||
char friends[MAX_FRIENDS][32];
|
||||
int friend_count;
|
||||
} User;
|
||||
|
||||
int load_users(User users[], int max_users);
|
||||
int save_users(User users[], int user_count);
|
||||
int find_user(User users[], int user_count, const char *username);
|
||||
int check_password(User users[], int user_count, const char *username, const char *password);
|
||||
int add_user(User users[], int *user_count, const char *username, const char *password);
|
||||
int add_friend(User users[], int user_count, const char *username, const char *friendname);
|
||||
|
||||
#endif
|
22
Project/新建文件夹/protocol.h
Normal file
22
Project/新建文件夹/protocol.h
Normal file
@ -0,0 +1,22 @@
|
||||
// protocol.h
|
||||
#ifndef PROTOCOL_H
|
||||
#define PROTOCOL_H
|
||||
|
||||
#define MSG_REGISTER 1
|
||||
#define MSG_LOGIN 2
|
||||
#define MSG_ADD_FRIEND 3
|
||||
#define MSG_PRIVATE_CHAT 4
|
||||
#define MSG_OK 100
|
||||
#define MSG_FAIL 101
|
||||
|
||||
#define MAX_NAME_LEN 32
|
||||
#define MAX_MSG_LEN 256
|
||||
|
||||
typedef struct {
|
||||
int type; // 消息类型
|
||||
char from[MAX_NAME_LEN];
|
||||
char to[MAX_NAME_LEN];
|
||||
char data[MAX_MSG_LEN];
|
||||
} Message;
|
||||
|
||||
#endif
|
1
Project/新建文件夹/users.txt
Normal file
1
Project/新建文件夹/users.txt
Normal file
@ -0,0 +1 @@
|
||||
test password
|
Loading…
Reference in New Issue
Block a user