This commit is contained in:
阿西布莱特 2025-06-10 23:43:56 +08:00
parent f1c858469d
commit d5eba67d09
30 changed files with 2490 additions and 0 deletions

8
Clion/.idea/.gitignore vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,7 @@
#include <stdio.h>
int main(void)
{
printf("Hello, World!\n");
return 0;
}

10
Clion/test.c Normal file
View 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

Binary file not shown.

0
Code/Project_Client.c Normal file
View File

0
Code/Project_Server.c Normal file
View File

54
Code/cet.c Normal file
View 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

Binary file not shown.

65
Code/ser.c Normal file
View 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

Binary file not shown.

270
Project/client.c Normal file
View 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

Binary file not shown.

471
Project/server.c Normal file
View 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
View 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", &current_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
View 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

Binary file not shown.

BIN
Project/test/server Normal file

Binary file not shown.

1
Project/users.txt Normal file
View File

@ -0,0 +1 @@
test password

View 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;
}

View 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;
}

View 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;
}

View 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

View 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

View File

@ -0,0 +1 @@
test password